home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / gcc263-src.lha / gcc-2.6.3 / config / arm / arm.md < prev    next >
Text File  |  1994-10-24  |  173KB  |  5,570 lines

  1. ;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
  2. ;;  Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
  3. ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
  4. ;;             and Martin Simmons (@harleqn.co.uk).
  5. ;;  More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
  6.  
  7. ;; This file is part of GNU CC.
  8.  
  9. ;; GNU CC is free software; you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation; either version 2, or (at your option)
  12. ;; any later version.
  13.  
  14. ;; GNU CC is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;; GNU General Public License for more details.
  18.  
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU CC; see the file COPYING.  If not, write to
  21. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  
  23. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  24.  
  25. ;; There are patterns in this file to support XFmode arithmetic.
  26. ;; Unfortunately RISC iX doesn't work well with these so they are disabled.
  27. ;; (See arm.h)
  28.  
  29. ;; UNSPEC Usage:
  30. ;; 0 `sin' operation: operand 0 is the result, operand 1 the parameter,
  31. ;;   the mode is MODE_FLOAT
  32. ;; 1 `cos' operation: operand 0 is the result, operand 1 the parameter,
  33. ;;   the mode is MODE_FLOAT
  34. ;; 2 `push multiple' operation: operand 0 is the first register.  Subsequent
  35. ;;   registers are in parallel (use...) expressions.
  36.  
  37. ;; Attributes
  38.  
  39. ; condition codes: this one is used by final_prescan_insn to speed up
  40. ; conditionalizing instructions.  It saves having to scan the rtl to see if
  41. ; it uses or alters the condition codes.
  42.  
  43. ; USE means that the condition codes are used by the insn in the process of
  44. ; outputting code, this means (at present) that we can't use the insn in
  45. ; inlined branches
  46.  
  47. ; SET means that the purpose of the insn is to set the condition codes in a
  48. ; well defined manner.
  49.  
  50. ; CLOB means that the condition codes are altered in an undefined manner, if
  51. ; they are altered at all
  52.  
  53. ; JUMP_CLOB is used when the conditions are not defined if a branch is taken,
  54. ; but are if the branch wasn't taken; the effect is to limit the branch
  55. ; elimination scanning.
  56.  
  57. ; NOCOND means that the condition codes are niether altered nor affect the
  58. ; output of this insn
  59.  
  60. (define_attr "conds" "use,set,clob,jump_clob,nocond"
  61.     (const_string "nocond"))
  62.  
  63. ; CPU attribute is used to determine whether condition codes are clobbered
  64. ; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the
  65. ; arm2 and arm3 the condition codes are restored by the return.
  66.  
  67. (define_attr "cpu" "arm2,arm3,arm6" (const (symbol_ref "arm_cpu_attr")))
  68.  
  69. ; Floating Point Unit.  If we only have floating point emulation, then there
  70. ; is no point in scheduling the floating point insns.  (Well, for best
  71. ; performance we should try and group them together).
  72.  
  73. (define_attr "fpu" "fpa,fpe" (const (symbol_ref "arm_fpu_attr")))
  74.  
  75. ; LENGTH of an instruction (in bytes)
  76. (define_attr "length" "" (const_int 4))
  77.  
  78. ; An assembler sequence may clobber the condition codes without us knowing
  79. (define_asm_attributes
  80.  [(set_attr "conds" "clob")
  81.   (set_attr "length" "4")])
  82.  
  83. ; TYPE attribute is used to detect floating point instructions which, if
  84. ; running on a co-processor can run in parallel with other, basic instructions
  85. ; If write-buffer scheduling is enabled then it can also be used in the
  86. ; scheduling of writes.
  87.  
  88. ; Classification of each insn
  89. ; normal    any data instruction that doesn't hit memory or fp regs
  90. ; block        blockage insn, this blocks all functional units
  91. ; float        a floating point arithmetic operation (subject to expansion)
  92. ; fdivx        XFmode floating point division
  93. ; fdivd        DFmode floating point division
  94. ; fdivs        SFmode floating point division
  95. ; fmul        Floating point multiply
  96. ; ffmul        Fast floating point multiply
  97. ; farith    Floating point arithmetic (4 cycle)
  98. ; ffarith    Fast floating point arithmetic (2 cycle)
  99. ; float_em    a floating point arithmetic operation that is normally emulated
  100. ;        even on a machine with an fpa.
  101. ; f_load    a floating point load from memory
  102. ; f_store    a floating point store to memory
  103. ; f_mem_r    a transfer of a floating point register to a real reg via mem
  104. ; r_mem_f    the reverse of f_mem_r
  105. ; f_2_r        fast transfer float to arm (no memory needed)
  106. ; r_2_f        fast transfer arm to float
  107. ; call        a subroutine call
  108. ; load        any load from memory
  109. ; store1    store 1 word to memory from arm registers
  110. ; store2    store 2 words
  111. ; store3    store 3 words
  112. ; store4    store 4 words
  113. ;
  114. (define_attr "type"
  115.     "normal,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4" 
  116.     (const_string "normal"))
  117.  
  118. (define_attr "write_conflict" "no,yes"
  119.   (if_then_else (eq_attr "type"
  120.          "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load")
  121.         (const_string "yes")
  122.         (const_string "no")))
  123.  
  124. ; The write buffer on some of the arm6 processors is hard to model exactly.
  125. ; There is room in the buffer for up to two addresses and up to eight words
  126. ; of memory, but the two needn't be split evenly.  When writing the two
  127. ; addresses are fully pipelined.  However, a read from memory that is not
  128. ; currently in the cache will block until the writes have completed.
  129. ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so
  130. ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
  131. ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
  132. ; cycle to add as well.
  133.  
  134. ;; (define_function_unit {name} {num-units} {n-users} {test}
  135. ;;                       {ready-delay} {issue-delay} [{conflict-list}])
  136. (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
  137.                      (eq_attr "type" "fdivx")) 71 69)
  138.  
  139. (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
  140.                      (eq_attr "type" "fdivd")) 59 57)
  141.  
  142. (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
  143.                      (eq_attr "type" "fdivs")) 31 29)
  144.  
  145. (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
  146.                      (eq_attr "type" "fmul")) 9 7)
  147.  
  148. (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
  149.                      (eq_attr "type" "ffmul")) 6 4)
  150.  
  151. (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
  152.                      (eq_attr "type" "farith")) 4 2)
  153.  
  154. (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
  155.                      (eq_attr "type" "ffarith")) 2 2)
  156.  
  157. (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
  158.                      (eq_attr "type" "r_2_f")) 5 3)
  159.  
  160. (define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
  161.                      (eq_attr "type" "f_2_r")) 1 2)
  162.  
  163. ;; The fpa10 doesn't really have a memory read unit, but it can start to
  164. ;; speculatively execute the instruction in the pipeline, provided the data
  165. ;; is already loaded, so pretend reads have a delay of 2 (and that the
  166. ;; pipeline is infinite.
  167.  
  168. (define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
  169.                      (eq_attr "type" "f_load")) 3 1)
  170.  
  171. (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 3 3
  172.     [(eq_attr "write_conflict" "yes")])
  173. (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 5 5
  174.     [(eq_attr "write_conflict" "yes")])
  175. (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 7 7
  176.     [(eq_attr "write_conflict" "yes")])
  177. (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 9 9
  178.     [(eq_attr "write_conflict" "yes")])
  179. (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 3 3
  180.     [(eq_attr "write_conflict" "yes")])
  181.  
  182. ;; Note: For DImode insns, there is normally no reason why operands should
  183. ;; not be in the same register, what we don't want is for something being
  184. ;; written to partially overlap something that is an input.
  185.  
  186. ;; Addition insns.
  187.  
  188. (define_insn "adddi3"
  189.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  190.     (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0")
  191.          (match_operand:DI 2 "s_register_operand" "r,0")))
  192.    (clobber (reg:CC 24))]
  193.   ""
  194.   "adds\\t%0, %1, %2\;adc\\t%R0, %R1, %R2"
  195. [(set_attr "conds" "clob")
  196.  (set_attr "length" "8")])
  197.  
  198. (define_insn ""
  199.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  200.     (plus:DI (sign_extend:DI
  201.           (match_operand:SI 1 "s_register_operand" "r,r"))
  202.          (match_operand:DI 2 "s_register_operand" "r,0")))
  203.    (clobber (reg:CC 24))]
  204.   ""
  205.   "adds\\t%0, %2, %1\;adc\\t%R0, %R2, %1, asr #31"
  206. [(set_attr "conds" "clob")
  207.  (set_attr "length" "8")])
  208.  
  209. (define_insn ""
  210.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  211.     (plus:DI (zero_extend:DI
  212.           (match_operand:SI 1 "s_register_operand" "r,r"))
  213.          (match_operand:DI 2 "s_register_operand" "r,0")))
  214.    (clobber (reg:CC 24))]
  215.   ""
  216.   "adds\\t%0, %2, %1\;adc\\t%R0, %R2, #0"
  217. [(set_attr "conds" "clob")
  218.  (set_attr "length" "8")])
  219.  
  220. (define_expand "addsi3"
  221.   [(set (match_operand:SI 0 "s_register_operand" "")
  222.     (plus:SI (match_operand:SI 1 "s_register_operand" "")
  223.          (match_operand:SI 2 "reg_or_int_operand" "")))]
  224.   ""
  225.   "
  226.   if (GET_CODE (operands[2]) == CONST_INT)
  227.     {
  228.       arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
  229.               operands[1],
  230.               (reload_in_progress || reload_completed ? 0
  231.                : preserve_subexpressions_p ()));
  232.       DONE;
  233.     }
  234. ")
  235.  
  236. (define_split
  237.   [(set (match_operand:SI 0 "s_register_operand" "")
  238.     (plus:SI (match_operand:SI 1 "s_register_operand" "")
  239.          (match_operand:SI 2 "const_int_operand" "")))]
  240.   "! (const_ok_for_arm (INTVAL (operands[2]))
  241.       || const_ok_for_arm (-INTVAL (operands[2])))"
  242.   [(clobber (const_int 0))]
  243.   "
  244.   arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
  245.               operands[1], 0);
  246.   DONE;
  247. ")
  248.  
  249. (define_insn ""
  250.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  251.     (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
  252.          (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
  253.   ""
  254.   "@
  255.    add%?\\t%0, %1, %2
  256.    sub%?\\t%0, %1, #%n2
  257.    #"
  258. [(set_attr "length" "4,4,16")])
  259.  
  260. (define_insn ""
  261.   [(set (reg:CC_NOOV 24)
  262.     (compare:CC_NOOV
  263.      (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
  264.           (match_operand:SI 2 "arm_add_operand" "rI,L"))
  265.      (const_int 0)))
  266.    (set (match_operand:SI 0 "s_register_operand" "=r,r")
  267.     (plus:SI (match_dup 1) (match_dup 2)))]
  268.   ""
  269.   "@
  270.    add%?s\\t%0, %1, %2
  271.    sub%?s\\t%0, %1, #%n2"
  272. [(set_attr "conds" "set")])
  273.  
  274. (define_insn ""
  275.   [(set (reg:CC 24)
  276.     (compare:CC (match_operand:SI 1 "s_register_operand" "r,r")
  277.             (neg:SI (match_operand:SI 2 "arm_add_operand" "rI,L"))))
  278.    (set (match_operand:SI 0 "s_register_operand" "=r,r")
  279.     (plus:SI (match_dup 1) (match_dup 2)))]
  280.   ""
  281.   "@
  282.    add%?s\\t%0, %1, %2
  283.    sub%?s\\t%0, %1, #%n2"
  284. [(set_attr "conds" "set")])
  285.  
  286. (define_insn "incscc"
  287.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  288.         (plus:SI (match_operator:SI 2 "comparison_operator"
  289.                     [(reg 24) (const_int 0)])
  290.                  (match_operand:SI 1 "s_register_operand" "0,?r")))]
  291.   ""
  292.   "@
  293.   add%d2\\t%0, %1, #1
  294.   mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
  295. [(set_attr "conds" "use")
  296.  (set_attr "length" "4,8")])
  297.  
  298. ; If a constant is too big to fit in a single instruction then the constant
  299. ; will be pre-loaded into a register taking at least two insns, we might be
  300. ; able to merge it with an add, but it depends on the exact value.
  301.  
  302. (define_split
  303.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  304.     (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  305.          (match_operand:SI 2 "immediate_operand" "n")))]
  306.   "!(const_ok_for_arm (INTVAL (operands[2]))
  307.      || const_ok_for_arm (-INTVAL (operands[2])))"
  308.   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
  309.    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
  310.   "
  311. {
  312.   unsigned int val = (unsigned) INTVAL (operands[2]);
  313.   int i;
  314.   unsigned int temp;
  315.  
  316.   /* this code is similar to the approach followed in movsi, but it must
  317.      generate exactly two insns */
  318.  
  319.   for (i = 30; i >= 0; i -= 2)
  320.     {
  321.       if (val & (3 << i))
  322.     {
  323.       i -= 6;
  324.       if (i < 0) i = 0;
  325.       if (const_ok_for_arm (temp = (val & ~(255 << i))))
  326.         {
  327.           val &= 255 << i;
  328.           break;
  329.         }
  330.       /* we might be able to do this as (larger number - small number) */
  331.       temp = ((val >> i) & 255) + 1;
  332.       if (temp > 255 && i < 24)
  333.         {
  334.           i += 2;
  335.           temp = ((val >> i) & 255) + 1;
  336.         }
  337.       if (const_ok_for_arm ((temp << i) - val))
  338.         {
  339.           i = temp << i;
  340.           temp = (unsigned) - (int) (i - val);
  341.           val = i;
  342.           break;
  343.         }
  344.       FAIL;
  345.     }
  346.     }
  347.   /* if we got here, we have found a way of doing it in two instructions.
  348.      the two constants are in val and temp */
  349.   operands[2] = GEN_INT ((int)val);
  350.   operands[3] = GEN_INT ((int)temp);
  351. }
  352. ")
  353.  
  354. (define_insn "addsf3"
  355.   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
  356.     (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
  357.          (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
  358.   ""
  359.   "@
  360.    adf%?s\\t%0, %1, %2
  361.    suf%?s\\t%0, %1, #%N2"
  362. [(set_attr "type" "farith")])
  363.  
  364. (define_insn "adddf3"
  365.   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
  366.     (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
  367.          (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
  368.   ""
  369.   "@
  370.    adf%?d\\t%0, %1, %2
  371.    suf%?d\\t%0, %1, #%N2"
  372. [(set_attr "type" "farith")])
  373.  
  374. (define_insn ""
  375.   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
  376.     (plus:DF (float_extend:DF
  377.           (match_operand:SF 1 "s_register_operand" "f,f"))
  378.          (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
  379.   ""
  380.   "@
  381.    adf%?d\\t%0, %1, %2
  382.    suf%?d\\t%0, %1, #%N2"
  383. [(set_attr "type" "farith")])
  384.  
  385. (define_insn ""
  386.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  387.     (plus:DF (match_operand:DF 1 "s_register_operand" "f")
  388.          (float_extend:DF
  389.           (match_operand:SF 2 "s_register_operand" "f"))))]
  390.   ""
  391.   "adf%?d\\t%0, %1, %2"
  392. [(set_attr "type" "farith")])
  393.  
  394. (define_insn ""
  395.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  396.     (plus:DF (float_extend:DF 
  397.           (match_operand:SF 1 "s_register_operand" "f"))
  398.          (float_extend:DF
  399.           (match_operand:SF 2 "s_register_operand" "f"))))]
  400.   ""
  401.   "adf%?d\\t%0, %1, %2"
  402. [(set_attr "type" "farith")])
  403.  
  404. (define_insn "addxf3"
  405.   [(set (match_operand:XF 0 "s_register_operand" "=f,f")
  406.     (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
  407.          (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
  408.   "ENABLE_XF_PATTERNS"
  409.   "@
  410.    adf%?e\\t%0, %1, %2
  411.    suf%?e\\t%0, %1, #%N2"
  412. [(set_attr "type" "farith")])
  413.  
  414. (define_insn "subdi3"
  415.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
  416.     (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
  417.           (match_operand:DI 2 "s_register_operand" "r,0,0")))
  418.    (clobber (reg:CC 24))]
  419.   ""
  420.   "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %R2"
  421. [(set_attr "conds" "clob")
  422.  (set_attr "length" "8")])
  423.  
  424. (define_insn ""
  425.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  426.     (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
  427.           (zero_extend:DI
  428.            (match_operand:SI 2 "s_register_operand" "r,r"))))
  429.    (clobber (reg:CC 24))]
  430.   ""
  431.   "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, #0"
  432. [(set_attr "conds" "clob")
  433.  (set_attr "length" "8")])
  434.  
  435. (define_insn ""
  436.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  437.     (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
  438.           (sign_extend:DI
  439.            (match_operand:SI 2 "s_register_operand" "r,r"))))
  440.    (clobber (reg:CC 24))]
  441.   ""
  442.   "subs\\t%0, %1, %2\;sbc\\t%R0, %R1, %2, asr #31"
  443. [(set_attr "conds" "clob")
  444.  (set_attr "length" "8")])
  445.  
  446. (define_insn ""
  447.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  448.     (minus:DI (zero_extend:DI
  449.            (match_operand:SI 2 "s_register_operand" "r,r"))
  450.           (match_operand:DI 1 "s_register_operand" "?r,0")))
  451.    (clobber (reg:CC 24))]
  452.   ""
  453.   "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, #0"
  454. [(set_attr "conds" "clob")
  455.  (set_attr "length" "8")])
  456.  
  457. (define_insn ""
  458.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  459.     (minus:DI (sign_extend:DI
  460.            (match_operand:SI 2 "s_register_operand" "r,r"))
  461.           (match_operand:DI 1 "s_register_operand" "?r,0")))
  462.    (clobber (reg:CC 24))]
  463.   ""
  464.   "rsbs\\t%0, %1, %2\;rsc\\t%R0, %R1, %2, asr #31"
  465. [(set_attr "conds" "clob")
  466.  (set_attr "length" "8")])
  467.  
  468. (define_insn ""
  469.   [(set (match_operand:DI 0 "s_register_operand" "=r")
  470.     (minus:DI (zero_extend:DI
  471.            (match_operand:SI 1 "s_register_operand" "r"))
  472.           (zero_extend:DI
  473.            (match_operand:SI 2 "s_register_operand" "r"))))
  474.    (clobber (reg:CC 24))]
  475.   ""
  476.   "subs\\t%0, %1, %2\;rsc\\t%R0, %1, %1"
  477. [(set_attr "conds" "clob")
  478.  (set_attr "length" "8")])
  479.  
  480. (define_expand "subsi3"
  481.   [(set (match_operand:SI 0 "s_register_operand" "")
  482.     (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
  483.           (match_operand:SI 2 "s_register_operand" "")))]
  484.   ""
  485.   "
  486.   if (GET_CODE (operands[1]) == CONST_INT)
  487.     {
  488.       arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
  489.               operands[2],
  490.               (reload_in_progress || reload_completed ? 0
  491.                : preserve_subexpressions_p ()));
  492.       DONE;
  493.     }
  494. ")
  495.  
  496. (define_insn ""
  497.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  498.     (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
  499.           (match_operand:SI 2 "s_register_operand" "r,r")))]
  500.   ""
  501.   "@
  502.    rsb%?\\t%0, %2, %1
  503.    #"
  504. [(set_attr "length" "4,16")])
  505.  
  506. (define_split
  507.   [(set (match_operand:SI 0 "s_register_operand" "")
  508.     (minus:SI (match_operand:SI 1 "const_int_operand" "")
  509.           (match_operand:SI 2 "s_register_operand" "")))]
  510.   "! const_ok_for_arm (INTVAL (operands[1]))"
  511.   [(clobber (const_int 0))]
  512.   "
  513.   arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
  514.               operands[2], 0);
  515.   DONE;
  516. ")
  517.  
  518. (define_insn ""
  519.   [(set (reg:CC_NOOV 24)
  520.     (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
  521.                  (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
  522.              (const_int 0)))
  523.    (set (match_operand:SI 0 "s_register_operand" "=r,r")
  524.     (minus:SI (match_dup 1) (match_dup 2)))]
  525.   ""
  526.   "@
  527.    sub%?s\\t%0, %1, %2
  528.    rsb%?s\\t%0, %2, %1"
  529. [(set_attr "conds" "set")])
  530.  
  531. (define_insn "decscc"
  532.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  533.         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
  534.           (match_operator:SI 2 "comparison_operator"
  535.                    [(reg 24) (const_int 0)])))]
  536.   ""
  537.   "@
  538.   sub%d2\\t%0, %1, #1
  539.   mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
  540. [(set_attr "conds" "use")
  541.  (set_attr "length" "*,8")])
  542.  
  543. (define_insn "subsf3"
  544.   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
  545.     (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
  546.           (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
  547.   ""
  548.   "@
  549.    suf%?s\\t%0, %1, %2
  550.    rsf%?s\\t%0, %2, %1"
  551. [(set_attr "type" "farith")])
  552.  
  553. (define_insn "subdf3"
  554.   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
  555.     (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
  556.           (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
  557.   ""
  558.   "@
  559.    suf%?d\\t%0, %1, %2
  560.    rsf%?d\\t%0, %2, %1"
  561. [(set_attr "type" "farith")])
  562.  
  563. (define_insn ""
  564.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  565.     (minus:DF (float_extend:DF
  566.            (match_operand:SF 1 "s_register_operand" "f"))
  567.           (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  568.   ""
  569.   "suf%?d\\t%0, %1, %2"
  570. [(set_attr "type" "farith")])
  571.  
  572. (define_insn ""
  573.   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
  574.     (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
  575.           (float_extend:DF
  576.            (match_operand:SF 2 "s_register_operand" "f,f"))))]
  577.   ""
  578.   "@
  579.    suf%?d\\t%0, %1, %2
  580.    rsf%?d\\t%0, %2, %1"
  581. [(set_attr "type" "farith")])
  582.  
  583. (define_insn ""
  584.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  585.     (minus:DF (float_extend:DF
  586.            (match_operand:SF 1 "s_register_operand" "f"))
  587.           (float_extend:DF
  588.            (match_operand:SF 2 "s_register_operand" "f"))))]
  589.   ""
  590.   "suf%?d\\t%0, %1, %2"
  591. [(set_attr "type" "farith")])
  592.  
  593. (define_insn "subxf3"
  594.   [(set (match_operand:XF 0 "s_register_operand" "=f,f")
  595.     (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
  596.           (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
  597.   "ENABLE_XF_PATTERNS"
  598.   "@
  599.    suf%?e\\t%0, %1, %2
  600.    rsf%?e\\t%0, %2, %1"
  601. [(set_attr "type" "farith")])
  602.  
  603. ;; Multiplication insns
  604.  
  605. ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
  606. (define_insn "mulsi3"
  607.   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
  608.     (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
  609.          (match_operand:SI 1 "s_register_operand" "%?r,0")))]
  610.   ""
  611.   "mul%?\\t%0, %2, %1")
  612.  
  613. (define_insn ""
  614.   [(set (reg:CC_NOOV 24)
  615.     (compare:CC_NOOV (mult:SI
  616.               (match_operand:SI 2 "s_register_operand" "r,r")
  617.               (match_operand:SI 1 "s_register_operand" "%?r,0"))
  618.              (const_int 0)))
  619.    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
  620.     (mult:SI (match_dup 2) (match_dup 1)))]
  621.   ""
  622.   "mul%?s\\t%0, %2, %1"
  623. [(set_attr "conds" "set")])
  624.  
  625. (define_insn ""
  626.   [(set (reg:CC_NOOV 24)
  627.     (compare:CC_NOOV (mult:SI
  628.               (match_operand:SI 2 "s_register_operand" "r,r")
  629.               (match_operand:SI 1 "s_register_operand" "%?r,0"))
  630.              (const_int 0)))
  631.    (clobber (match_scratch:SI 0 "=&r,&r"))]
  632.   ""
  633.   "mul%?s\\t%0, %2, %1"
  634. [(set_attr "conds" "set")])
  635.  
  636. ;; Unnamed templates to match MLA instruction.
  637.  
  638. (define_insn ""
  639.   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
  640.     (plus:SI
  641.       (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
  642.            (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
  643.       (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
  644.   ""
  645.   "mla%?\\t%0, %2, %1, %3")
  646.  
  647. (define_insn ""
  648.   [(set (reg:CC_NOOV 24)
  649.     (compare:CC_NOOV (plus:SI
  650.               (mult:SI
  651.                (match_operand:SI 2 "s_register_operand" "r,r,r,r")
  652.                (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
  653.               (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
  654.              (const_int 0)))
  655.    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
  656.     (plus:SI (mult:SI (match_dup 2) (match_dup 1))
  657.          (match_dup 3)))]
  658.   ""
  659.   "mla%?s\\t%0, %2, %1, %3"
  660. [(set_attr "conds" "set")])
  661.  
  662. (define_insn ""
  663.   [(set (reg:CC_NOOV 24)
  664.     (compare:CC_NOOV (plus:SI
  665.               (mult:SI
  666.                (match_operand:SI 2 "s_register_operand" "r,r,r,r")
  667.                (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
  668.               (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
  669.              (const_int 0)))
  670.    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
  671.   ""
  672.   "mla%?s\\t%0, %2, %1, %3"
  673. [(set_attr "conds" "set")])
  674.  
  675. (define_insn "mulsf3"
  676.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  677.     (mult:SF (match_operand:SF 1 "s_register_operand" "f")
  678.          (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
  679.   ""
  680.   "fml%?s\\t%0, %1, %2"
  681. [(set_attr "type" "ffmul")])
  682.  
  683. (define_insn "muldf3"
  684.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  685.     (mult:DF (match_operand:DF 1 "s_register_operand" "f")
  686.          (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  687.   ""
  688.   "muf%?d\\t%0, %1, %2"
  689. [(set_attr "type" "fmul")])
  690.  
  691. (define_insn ""
  692.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  693.     (mult:DF (float_extend:DF
  694.           (match_operand:SF 1 "s_register_operand" "f"))
  695.          (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  696.   ""
  697.   "muf%?d\\t%0, %1, %2"
  698. [(set_attr "type" "fmul")])
  699.  
  700. (define_insn ""
  701.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  702.     (mult:DF (match_operand:DF 1 "s_register_operand" "f")
  703.          (float_extend:DF
  704.           (match_operand:SF 2 "s_register_operand" "f"))))]
  705.   ""
  706.   "muf%?d\\t%0, %1, %2"
  707. [(set_attr "type" "fmul")])
  708.  
  709. (define_insn ""
  710.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  711.     (mult:DF (float_extend:DF
  712.           (match_operand:SF 1 "s_register_operand" "f"))
  713.          (float_extend:DF
  714.           (match_operand:SF 2 "s_register_operand" "f"))))]
  715.   ""
  716.   "muf%?d\\t%0, %1, %2"
  717. [(set_attr "type" "fmul")])
  718.  
  719. (define_insn "mulxf3"
  720.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  721.     (mult:XF (match_operand:XF 1 "s_register_operand" "f")
  722.          (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
  723.   "ENABLE_XF_PATTERNS"
  724.   "muf%?e\\t%0, %1, %2"
  725. [(set_attr "type" "fmul")])
  726.  
  727. ;; Division insns
  728.  
  729. (define_insn "divsf3"
  730.   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
  731.     (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
  732.         (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
  733.   ""
  734.   "@
  735.    fdv%?s\\t%0, %1, %2
  736.    frd%?s\\t%0, %2, %1"
  737. [(set_attr "type" "fdivs")])
  738.  
  739. (define_insn "divdf3"
  740.   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
  741.     (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
  742.         (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
  743.   ""
  744.   "@
  745.    dvf%?d\\t%0, %1, %2
  746.    rdf%?d\\t%0, %2, %1"
  747. [(set_attr "type" "fdivd")])
  748.  
  749. (define_insn ""
  750.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  751.     (div:DF (float_extend:DF
  752.          (match_operand:SF 1 "s_register_operand" "f"))
  753.         (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  754.   ""
  755.   "dvf%?d\\t%0, %1, %2"
  756. [(set_attr "type" "fdivd")])
  757.  
  758. (define_insn ""
  759.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  760.     (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
  761.         (float_extend:DF
  762.          (match_operand:SF 2 "s_register_operand" "f"))))]
  763.   ""
  764.   "rdf%?d\\t%0, %2, %1"
  765. [(set_attr "type" "fdivd")])
  766.  
  767. (define_insn ""
  768.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  769.     (div:DF (float_extend:DF
  770.          (match_operand:SF 1 "s_register_operand" "f"))
  771.         (float_extend:DF
  772.          (match_operand:SF 2 "s_register_operand" "f"))))]
  773.   ""
  774.   "dvf%?d\\t%0, %1, %2"
  775. [(set_attr "type" "fdivd")])
  776.  
  777. (define_insn "divxf3"
  778.   [(set (match_operand:XF 0 "s_register_operand" "=f,f")
  779.     (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
  780.         (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
  781.   "ENABLE_XF_PATTERNS"
  782.   "@
  783.    dvf%?e\\t%0, %1, %2
  784.    rdf%?e\\t%0, %2, %1"
  785. [(set_attr "type" "fdivx")])
  786.  
  787. ;; Modulo insns
  788.  
  789. (define_insn "modsf3"
  790.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  791.     (mod:SF (match_operand:SF 1 "s_register_operand" "f")
  792.         (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
  793.   ""
  794.   "rmf%?s\\t%0, %1, %2"
  795. [(set_attr "type" "fdivs")])
  796.  
  797. (define_insn "moddf3"
  798.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  799.     (mod:DF (match_operand:DF 1 "s_register_operand" "f")
  800.         (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  801.   ""
  802.   "rmf%?d\\t%0, %1, %2"
  803. [(set_attr "type" "fdivd")])
  804.  
  805. (define_insn ""
  806.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  807.     (mod:DF (float_extend:DF
  808.          (match_operand:SF 1 "s_register_operand" "f"))
  809.         (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
  810.   ""
  811.   "rmf%?d\\t%0, %1, %2"
  812. [(set_attr "type" "fdivd")])
  813.  
  814. (define_insn ""
  815.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  816.     (mod:DF (match_operand:DF 1 "s_register_operand" "f")
  817.         (float_extend:DF
  818.          (match_operand:SF 2 "s_register_operand" "f"))))]
  819.   ""
  820.   "rmf%?d\\t%0, %1, %2"
  821. [(set_attr "type" "fdivd")])
  822.  
  823. (define_insn ""
  824.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  825.     (mod:DF (float_extend:DF
  826.          (match_operand:SF 1 "s_register_operand" "f"))
  827.         (float_extend:DF
  828.          (match_operand:SF 2 "s_register_operand" "f"))))]
  829.   ""
  830.   "rmf%?d\\t%0, %1, %2"
  831. [(set_attr "type" "fdivd")])
  832.  
  833. (define_insn "modxf3"
  834.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  835.     (mod:XF (match_operand:XF 1 "s_register_operand" "f")
  836.         (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
  837.   "ENABLE_XF_PATTERNS"
  838.   "rmf%?e\\t%0, %1, %2"
  839. [(set_attr "type" "fdivx")])
  840.  
  841. ;; Boolean and,ior,xor insns
  842.  
  843. (define_insn "anddi3"
  844.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  845.     (and:DI (match_operand:DI 1 "s_register_operand" "%0,0")
  846.         (match_operand:DI 2 "s_register_operand" "r,0")))]
  847.   ""
  848.   "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %R2"
  849. [(set_attr "length" "8")])
  850.  
  851. (define_insn ""
  852.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  853.     (and:DI (zero_extend:DI
  854.          (match_operand:SI 2 "s_register_operand" "r,r"))
  855.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  856.   ""
  857.   "and%?\\t%0, %1, %2\;mov%?\\t%R0, #0"
  858. [(set_attr "length" "8")])
  859.  
  860. (define_insn ""
  861.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  862.     (and:DI (sign_extend:DI
  863.          (match_operand:SI 2 "s_register_operand" "r,r"))
  864.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  865.   ""
  866.   "and%?\\t%0, %1, %2\;and%?\\t%R0, %R1, %2, asr #31"
  867. [(set_attr "length" "8")])
  868.  
  869. (define_expand "andsi3"
  870.   [(set (match_operand:SI 0 "s_register_operand" "")
  871.     (and:SI (match_operand:SI 1 "s_register_operand" "")
  872.         (match_operand:SI 2 "reg_or_int_operand" "")))]
  873.   ""
  874.   "
  875.   if (GET_CODE (operands[2]) == CONST_INT)
  876.     {
  877.       arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
  878.               operands[1],
  879.               (reload_in_progress || reload_completed
  880.                ? 0 : preserve_subexpressions_p ()));
  881.       DONE;
  882.     }
  883. ")
  884.  
  885. (define_insn ""
  886.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  887.     (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
  888.         (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
  889.   ""
  890.   "@
  891.    and%?\\t%0, %1, %2
  892.    bic%?\\t%0, %1, #%B2
  893.    #"
  894. [(set_attr "length" "4,4,16")])
  895.  
  896. (define_split
  897.   [(set (match_operand:SI 0 "s_register_operand" "")
  898.     (and:SI (match_operand:SI 1 "s_register_operand" "")
  899.         (match_operand:SI 2 "const_int_operand" "")))]
  900.   "! (const_ok_for_arm (INTVAL (operands[2]))
  901.       || const_ok_for_arm (~ INTVAL (operands[2])))"
  902.   [(clobber (const_int 0))]
  903.   "
  904.   arm_split_constant  (AND, SImode, INTVAL (operands[2]), operands[0],
  905.                operands[1], 0);
  906.   DONE;
  907. ")
  908.  
  909. (define_insn ""
  910.   [(set (reg:CC_NOOV 24)
  911.     (compare:CC_NOOV
  912.      (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
  913.          (match_operand:SI 2 "arm_not_operand" "rI,K"))
  914.      (const_int 0)))
  915.    (set (match_operand:SI 0 "s_register_operand" "=r,r")
  916.     (and:SI (match_dup 1) (match_dup 2)))]
  917.   ""
  918.   "@
  919.    and%?s\\t%0, %1, %2
  920.    bic%?s\\t%0, %1, #%B2"
  921. [(set_attr "conds" "set")])
  922.  
  923. (define_insn ""
  924.   [(set (reg:CC_NOOV 24)
  925.     (compare:CC_NOOV
  926.      (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
  927.          (match_operand:SI 1 "arm_not_operand" "rI,K"))
  928.      (const_int 0)))
  929.    (clobber (match_scratch:SI 3 "=X,r"))]
  930.   ""
  931.   "@
  932.    tst%?\\t%0, %1
  933.    bic%?s\\t%3, %0, #%B1"
  934. [(set_attr "conds" "set")])
  935.  
  936. (define_insn ""
  937.   [(set (reg:CC_NOOV 24)
  938.     (compare:CC_NOOV (zero_extract:SI
  939.               (match_operand:SI 0 "s_register_operand" "r")
  940.                (match_operand:SI 1 "immediate_operand" "n")
  941.               (match_operand:SI 2 "immediate_operand" "n"))
  942.              (const_int 0)))]
  943.   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
  944.    && INTVAL (operands[1]) > 0 
  945.    && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
  946.    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32"
  947.   "*
  948. {
  949.   unsigned int mask = 0;
  950.   int cnt = INTVAL (operands[1]);
  951.   
  952.   while (cnt--)
  953.     mask = (mask << 1) | 1;
  954.   operands[1] = GEN_INT (mask << INTVAL (operands[2]));
  955.   output_asm_insn (\"tst%?\\t%0, %1\", operands);
  956.   return \"\";
  957. }
  958. "
  959. [(set_attr "conds" "set")])
  960.  
  961. (define_insn ""
  962.   [(set (reg:CC_NOOV 24)
  963.     (compare:CC_NOOV (zero_extract:SI
  964.               (match_operand:QI 0 "memory_operand" "m")
  965.                (match_operand 1 "immediate_operand" "n")
  966.               (match_operand 2 "immediate_operand" "n"))
  967.              (const_int 0)))
  968.    (clobber (match_scratch:QI 3 "=r"))]
  969.   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8
  970.    && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8"
  971.   "*
  972. {
  973.   unsigned int mask = 0;
  974.   int cnt = INTVAL (operands[1]);
  975.   
  976.   while (cnt--)
  977.     mask = (mask << 1) | 1;
  978.   operands[1] = GEN_INT (mask << INTVAL (operands[2]));
  979.   output_asm_insn (\"ldr%?b\\t%3, %0\", operands);
  980.   output_asm_insn (\"tst%?\\t%3, %1\", operands);
  981.   return \"\";
  982. }
  983. "
  984. [(set_attr "conds" "set")
  985.  (set_attr "length" "8")])
  986.  
  987. ;; constants for op 2 will never be given to these patterns.
  988. (define_insn ""
  989.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  990.     (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
  991.         (match_operand:DI 1 "s_register_operand" "0,r")))]
  992.   ""
  993.   "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %R2"
  994. [(set_attr "length" "8")])
  995.   
  996. (define_insn ""
  997.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  998.     (and:DI (not:DI (zero_extend:DI
  999.              (match_operand:SI 2 "s_register_operand" "r,r")))
  1000.         (match_operand:DI 1 "s_register_operand" "0,?r")))]
  1001.   ""
  1002.   "@
  1003.    bic%?\\t%0, %1, %2
  1004.    bic%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
  1005. [(set_attr "length" "4,8")])
  1006.   
  1007. (define_insn ""
  1008.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1009.     (and:DI (not:DI (sign_extend:DI
  1010.              (match_operand:SI 2 "s_register_operand" "r,r")))
  1011.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1012.   ""
  1013.   "bic%?\\t%0, %1, %2\;bic%?\\t%R0, %R1, %2, asr #31"
  1014. [(set_attr "length" "8")])
  1015.   
  1016. (define_insn ""
  1017.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1018.     (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
  1019.         (match_operand:SI 1 "s_register_operand" "r")))]
  1020.   ""
  1021.   "bic%?\\t%0, %1, %2")
  1022.  
  1023. (define_insn ""
  1024.   [(set (reg:CC_NOOV 24)
  1025.     (compare:CC_NOOV
  1026.      (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
  1027.          (match_operand:SI 1 "s_register_operand" "r"))
  1028.      (const_int 0)))
  1029.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1030.     (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
  1031.   ""
  1032.   "bic%?s\\t%0, %1, %2"
  1033. [(set_attr "conds" "set")])
  1034.  
  1035. (define_insn ""
  1036.   [(set (reg:CC_NOOV 24)
  1037.     (compare:CC_NOOV
  1038.      (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
  1039.          (match_operand:SI 1 "s_register_operand" "r"))
  1040.      (const_int 0)))
  1041.    (clobber (match_scratch:SI 0 "=r"))]
  1042.   ""
  1043.   "bic%?s\\t%0, %1, %2"
  1044. [(set_attr "conds" "set")])
  1045.  
  1046. (define_insn "iordi3"
  1047.   [(set (match_operand:DI 0 "s_register_operand" "=&r")
  1048.     (ior:DI (match_operand:DI 1 "s_register_operand" "%0")
  1049.         (match_operand:DI 2 "s_register_operand" "r")))]
  1050.   ""
  1051.   "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %R2"
  1052. [(set_attr "length" "8")])
  1053.  
  1054. (define_insn ""
  1055.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1056.     (ior:DI (zero_extend:DI
  1057.          (match_operand:SI 2 "s_register_operand" "r,r"))
  1058.         (match_operand:DI 1 "s_register_operand" "0,?r")))]
  1059.   ""
  1060.   "@
  1061.    orr%?\\t%0, %1, %2
  1062.    orr%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
  1063. [(set_attr "length" "4,8")])
  1064.  
  1065. (define_insn ""
  1066.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1067.     (ior:DI (sign_extend:DI
  1068.          (match_operand:SI 2 "s_register_operand" "r,r"))
  1069.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1070.   ""
  1071.   "orr%?\\t%0, %1, %2\;orr%?\\t%R0, %R1, %2, asr #31"
  1072. [(set_attr "length" "8")])
  1073.  
  1074. (define_expand "iorsi3"
  1075.   [(set (match_operand:SI 0 "s_register_operand" "")
  1076.     (ior:SI (match_operand:SI 1 "s_register_operand" "")
  1077.         (match_operand:SI 2 "reg_or_int_operand" "")))]
  1078.   ""
  1079.   "
  1080.   if (GET_CODE (operands[2]) == CONST_INT)
  1081.     {
  1082.       arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
  1083.               operands[1],
  1084.               (reload_in_progress || reload_completed
  1085.                ? 0 : preserve_subexpressions_p ()));
  1086.       DONE;
  1087.     }
  1088. ")
  1089.  
  1090. (define_insn ""
  1091.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  1092.     (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
  1093.         (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
  1094.   ""
  1095.   "@
  1096.    orr%?\\t%0, %1, %2
  1097.    #"
  1098. [(set_attr "length" "4,16")])
  1099.  
  1100. (define_split
  1101.   [(set (match_operand:SI 0 "s_register_operand" "")
  1102.     (ior:SI (match_operand:SI 1 "s_register_operand" "")
  1103.         (match_operand:SI 2 "const_int_operand" "")))]
  1104.   "! const_ok_for_arm (INTVAL (operands[2]))"
  1105.   [(clobber (const_int 0))]
  1106.   "
  1107.   arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
  1108.               operands[1], 0);
  1109.   DONE;
  1110. ")
  1111.   
  1112. (define_insn ""
  1113.   [(set (reg:CC_NOOV 24)
  1114.     (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
  1115.                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
  1116.              (const_int 0)))
  1117.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1118.     (ior:SI (match_dup 1) (match_dup 2)))]
  1119.   ""
  1120.   "orr%?s\\t%0, %1, %2"
  1121. [(set_attr "conds" "set")])
  1122.  
  1123. (define_insn ""
  1124.   [(set (reg:CC_NOOV 24)
  1125.     (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
  1126.                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
  1127.              (const_int 0)))
  1128.    (clobber (match_scratch:SI 0 "=r"))]
  1129.   ""
  1130.   "orr%?s\\t%0, %1, %2"
  1131. [(set_attr "conds" "set")])
  1132.  
  1133. (define_insn "xordi3"
  1134.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1135.     (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0")
  1136.         (match_operand:DI 2 "s_register_operand" "r,0")))]
  1137.   ""
  1138.   "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %R2"
  1139. [(set_attr "length" "8")])
  1140.  
  1141. (define_insn ""
  1142.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1143.     (xor:DI (zero_extend:DI
  1144.          (match_operand:SI 2 "s_register_operand" "r,r"))
  1145.         (match_operand:DI 1 "s_register_operand" "0,?r")))]
  1146.   ""
  1147.   "@
  1148.    eor%?\\t%0, %1, %2
  1149.    eor%?\\t%0, %1, %2\;mov%?\\t%R0, %R1"
  1150. [(set_attr "length" "4,8")])
  1151.  
  1152. (define_insn ""
  1153.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1154.     (xor:DI (sign_extend:DI
  1155.          (match_operand:SI 2 "s_register_operand" "r,r"))
  1156.         (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1157.   ""
  1158.   "eor%?\\t%0, %1, %2\;eor%?\\t%R0, %R1, %2, asr #31"
  1159. [(set_attr "length" "8")])
  1160.  
  1161. (define_insn "xorsi3"
  1162.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1163.     (xor:SI (match_operand:SI 1 "s_register_operand" "r")
  1164.         (match_operand:SI 2 "arm_rhs_operand" "rI")))]
  1165.   ""
  1166.   "eor%?\\t%0, %1, %2")
  1167.  
  1168. (define_insn ""
  1169.   [(set (reg:CC_NOOV 24)
  1170.     (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
  1171.                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
  1172.              (const_int 0)))
  1173.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1174.     (xor:SI (match_dup 1) (match_dup 2)))]
  1175.   ""
  1176.   "eor%?s\\t%0, %1, %2"
  1177. [(set_attr "conds" "set")])
  1178.  
  1179. (define_insn ""
  1180.   [(set (reg:CC_NOOV 24)
  1181.     (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
  1182.                  (match_operand:SI 1 "arm_rhs_operand" "rI"))
  1183.              (const_int 0)))]
  1184.   ""
  1185.   "teq%?\\t%0, %1"
  1186. [(set_attr "conds" "set")])
  1187.  
  1188. ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
  1189. ;; (NOT D) we can sometimes merge the final NOT into one of the following
  1190. ;; insns
  1191.  
  1192. (define_split
  1193.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1194.     (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r"))
  1195.             (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI")))
  1196.         (match_operand:SI 3 "arm_rhs_operand" "rI")))
  1197.    (clobber (match_operand:SI 4 "s_register_operand" "=r"))]
  1198.   ""
  1199.   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
  1200.                   (not:SI (match_dup 3))))
  1201.    (set (match_dup 0) (not:SI (match_dup 4)))]
  1202.   ""
  1203. )
  1204.  
  1205. (define_insn ""
  1206.   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
  1207.     (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
  1208.             (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
  1209.         (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
  1210.   ""
  1211.   "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
  1212. [(set_attr "length" "8")])
  1213.  
  1214.  
  1215.  
  1216. ;; Minimum and maximum insns
  1217.  
  1218. (define_insn "smaxsi3"
  1219.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  1220.     (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
  1221.          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
  1222.    (clobber (reg:CC 24))]
  1223.   ""
  1224.   "@
  1225.    cmp\\t%1, %2\;movlt\\t%0, %2
  1226.    cmp\\t%1, %2\;movge\\t%0, %1
  1227.    cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
  1228. [(set_attr "conds" "clob")
  1229.  (set_attr "length" "8,8,12")])
  1230.  
  1231. (define_insn "sminsi3"
  1232.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  1233.     (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
  1234.          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
  1235.    (clobber (reg:CC 24))]
  1236.   ""
  1237.   "@
  1238.    cmp\\t%1, %2\;movge\\t%0, %2
  1239.    cmp\\t%1, %2\;movlt\\t%0, %1
  1240.    cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
  1241. [(set_attr "conds" "clob")
  1242.  (set_attr "length" "8,8,12")])
  1243.  
  1244. (define_insn "umaxsi3"
  1245.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  1246.     (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
  1247.          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
  1248.    (clobber (reg:CC 24))]
  1249.   ""
  1250.   "@
  1251.    cmp\\t%1, %2\;movcc\\t%0, %2
  1252.    cmp\\t%1, %2\;movcs\\t%0, %1
  1253.    cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
  1254. [(set_attr "conds" "clob")
  1255.  (set_attr "length" "8,8,12")])
  1256.  
  1257. (define_insn "uminsi3"
  1258.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  1259.     (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
  1260.          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
  1261.    (clobber (reg:CC 24))]
  1262.   ""
  1263.   "@
  1264.    cmp\\t%1, %2\;movcs\\t%0, %2
  1265.    cmp\\t%1, %2\;movcc\\t%0, %1
  1266.    cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
  1267. [(set_attr "conds" "clob")
  1268.  (set_attr "length" "8,8,12")])
  1269.  
  1270. (define_insn ""
  1271.   [(set (match_operand:SI 0 "memory_operand" "=m")
  1272.     (match_operator:SI 3 "minmax_operator"
  1273.      [(match_operand:SI 1 "s_register_operand" "r")
  1274.       (match_operand:SI 2 "s_register_operand" "r")]))
  1275.    (clobber (reg:CC 24))]
  1276.   ""
  1277.   "*
  1278.   operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1],
  1279.              operands[2]);
  1280.   output_asm_insn (\"cmp\\t%1, %2\", operands);
  1281.   output_asm_insn (\"str%d3\\t%1, %0\", operands);
  1282.   output_asm_insn (\"str%D3\\t%2, %0\", operands);
  1283.   return \"\";
  1284. "
  1285. [(set_attr "conds" "clob")
  1286.  (set_attr "length" "12")
  1287.  (set_attr "type" "store1")])
  1288.  
  1289. (define_insn ""
  1290.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  1291.     (match_operator:SI 4 "shiftable_operator"
  1292.      [(match_operator:SI 5 "minmax_operator"
  1293.        [(match_operand:SI 2 "s_register_operand" "r,r")
  1294.         (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
  1295.       (match_operand:SI 1 "s_register_operand" "0,?r")]))
  1296.    (clobber (reg:CC 24))]
  1297.   ""
  1298.   "*
  1299. {
  1300.   enum rtx_code code = GET_CODE (operands[4]);
  1301.  
  1302.   operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2],
  1303.              operands[3]);
  1304.   output_asm_insn (\"cmp\\t%2, %3\", operands);
  1305.   output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
  1306.   if (which_alternative != 0 || operands[3] != const0_rtx
  1307.       || (code != PLUS && code != MINUS && code != IOR && code != XOR))
  1308.     output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
  1309.   return \"\";
  1310. }
  1311. "
  1312. [(set_attr "conds" "clob")
  1313.  (set_attr "length" "12")])
  1314.  
  1315.  
  1316. ;; Shift and rotation insns
  1317.  
  1318. (define_expand "ashlsi3"
  1319.   [(set (match_operand:SI 0 "s_register_operand" "")
  1320.     (ashift:SI (match_operand:SI 1 "s_register_operand" "")
  1321.            (match_operand:SI 2 "arm_rhs_operand" "")))]
  1322.   ""
  1323.   "
  1324.   if (GET_CODE (operands[2]) == CONST_INT
  1325.       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
  1326.     {
  1327.       emit_insn (gen_movsi (operands[0], const0_rtx));
  1328.       DONE;
  1329.     }
  1330. ")
  1331.  
  1332. (define_expand "ashrsi3"
  1333.   [(set (match_operand:SI 0 "s_register_operand" "")
  1334.     (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
  1335.              (match_operand:SI 2 "arm_rhs_operand" "")))]
  1336.   ""
  1337.   "
  1338.   if (GET_CODE (operands[2]) == CONST_INT
  1339.       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
  1340.     operands[2] = GEN_INT (31);
  1341. ")
  1342.  
  1343. (define_expand "lshrsi3"
  1344.   [(set (match_operand:SI 0 "s_register_operand" "")
  1345.     (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
  1346.              (match_operand:SI 2 "arm_rhs_operand" "")))]
  1347.   ""
  1348.   "
  1349.   if (GET_CODE (operands[2]) == CONST_INT
  1350.       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
  1351.     {
  1352.       emit_insn (gen_movsi (operands[0], const0_rtx));
  1353.       DONE;
  1354.     }
  1355. ")
  1356.  
  1357. (define_expand "rotlsi3"
  1358.   [(set (match_operand:SI 0 "s_register_operand" "")
  1359.     (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
  1360.              (match_operand:SI 2 "reg_or_int_operand" "")))]
  1361.   ""
  1362.   "
  1363.   if (GET_CODE (operands[2]) == CONST_INT)
  1364.     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
  1365.   else
  1366.     {
  1367.       rtx reg = gen_reg_rtx (SImode);
  1368.       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
  1369.       operands[2] = reg;
  1370.     }
  1371. ")
  1372.  
  1373. (define_expand "rotrsi3"
  1374.   [(set (match_operand:SI 0 "s_register_operand" "")
  1375.     (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
  1376.              (match_operand:SI 2 "arm_rhs_operand" "")))]
  1377.   ""
  1378.   "
  1379.   if (GET_CODE (operands[2]) == CONST_INT
  1380.       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
  1381.     operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
  1382. ")
  1383.  
  1384. (define_insn ""
  1385.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1386.     (match_operator:SI 3 "shift_operator"
  1387.      [(match_operand:SI 1 "s_register_operand" "r")
  1388.       (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
  1389.   ""
  1390.   "mov%?\\t%0, %1%S3")
  1391.  
  1392. (define_insn ""
  1393.   [(set (reg:CC_NOOV 24)
  1394.     (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
  1395.               [(match_operand:SI 1 "s_register_operand" "r")
  1396.                (match_operand:SI 2 "arm_rhs_operand" "rM")])
  1397.              (const_int 0)))
  1398.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1399.     (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
  1400.   ""
  1401.   "mov%?s\\t%0, %1%S3"
  1402. [(set_attr "conds" "set")])
  1403.  
  1404. (define_insn ""
  1405.   [(set (reg:CC_NOOV 24)
  1406.     (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
  1407.               [(match_operand:SI 1 "s_register_operand" "r")
  1408.                (match_operand:SI 2 "arm_rhs_operand" "rM")])
  1409.              (const_int 0)))
  1410.    (clobber (match_scratch:SI 0 "=r"))]
  1411.   ""
  1412.   "mov%?s\\t%0, %1%S3"
  1413. [(set_attr "conds" "set")])
  1414.  
  1415. (define_insn ""
  1416.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1417.     (not:SI (match_operator:SI 3 "shift_operator"
  1418.          [(match_operand:SI 1 "s_register_operand" "r")
  1419.           (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
  1420.   ""
  1421.   "mvn%?\\t%0, %1%S3")
  1422.  
  1423. (define_insn ""
  1424.   [(set (reg:CC_NOOV 24)
  1425.     (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
  1426.               [(match_operand:SI 1 "s_register_operand" "r")
  1427.                (match_operand:SI 2 "arm_rhs_operand" "rM")]))
  1428.              (const_int 0)))
  1429.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1430.     (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
  1431.   ""
  1432.   "mvn%?s\\t%0, %1%S3"
  1433. [(set_attr "conds" "set")])
  1434.  
  1435. (define_insn ""
  1436.   [(set (reg:CC_NOOV 24)
  1437.     (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
  1438.               [(match_operand:SI 1 "s_register_operand" "r")
  1439.                (match_operand:SI 2 "arm_rhs_operand" "rM")]))
  1440.              (const_int 0)))
  1441.    (clobber (match_scratch:SI 0 "=r"))]
  1442.   ""
  1443.   "mvn%?s\\t%0, %1%S3"
  1444. [(set_attr "conds" "set")])
  1445.  
  1446.  
  1447. ;; Unary arithmetic insns
  1448.  
  1449. (define_insn "negdi2"
  1450.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1451.     (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1452.   ""
  1453.   "rsbs\\t%0, %1, #0\;rsc\\t%R0, %R1, #0"
  1454. [(set_attr "conds" "clob")
  1455.  (set_attr "length" "8")])
  1456.  
  1457. (define_insn "negsi2"
  1458.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1459.     (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
  1460.   ""
  1461.   "rsb%?\\t%0, %1, #0")
  1462.  
  1463. (define_insn "negsf2"
  1464.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1465.     (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
  1466.   ""
  1467.   "mnf%?s\\t%0, %1"
  1468. [(set_attr "type" "ffarith")])
  1469.  
  1470. (define_insn "negdf2"
  1471.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1472.     (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
  1473.   ""
  1474.   "mnf%?d\\t%0, %1"
  1475. [(set_attr "type" "ffarith")])
  1476.  
  1477. (define_insn ""
  1478.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1479.     (neg:DF (float_extend:DF
  1480.          (match_operand:SF 1 "s_register_operand" "f"))))]
  1481.   ""
  1482.   "mnf%?d\\t%0, %1"
  1483. [(set_attr "type" "ffarith")])
  1484.  
  1485. (define_insn "negxf2"
  1486.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1487.     (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
  1488.   "ENABLE_XF_PATTERNS"
  1489.   "mnf%?e\\t%0, %1"
  1490. [(set_attr "type" "ffarith")])
  1491.  
  1492. ;; abssi2 doesn't really clobber the condition codes if a different register
  1493. ;; is being set.  To keep things simple, assume during rtl manipulations that
  1494. ;; it does, but tell the final scan operator the truth.  Similarly for
  1495. ;; (neg (abs...))
  1496.  
  1497. (define_insn "abssi2"
  1498.   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
  1499.     (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
  1500.    (clobber (reg 24))]
  1501.   ""
  1502.   "@
  1503.    cmp\\t%0, #0\;rsblt\\t%0, %0, #0
  1504.    eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
  1505. [(set_attr "conds" "clob,*")
  1506.  (set_attr "length" "8")])
  1507.  
  1508. (define_insn ""
  1509.   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
  1510.     (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
  1511.    (clobber (reg 24))]
  1512.   ""
  1513.   "@
  1514.    cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
  1515.    eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
  1516. [(set_attr "conds" "clob,*")
  1517.  (set_attr "length" "8")])
  1518.  
  1519. (define_insn "abssf2"
  1520.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1521.      (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
  1522.   ""
  1523.   "abs%?s\\t%0, %1"
  1524. [(set_attr "type" "ffarith")])
  1525.  
  1526. (define_insn "absdf2"
  1527.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1528.     (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
  1529.   ""
  1530.   "abs%?d\\t%0, %1"
  1531. [(set_attr "type" "ffarith")])
  1532.  
  1533. (define_insn ""
  1534.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1535.     (abs:DF (float_extend:DF
  1536.          (match_operand:SF 1 "s_register_operand" "f"))))]
  1537.   ""
  1538.   "abs%?d\\t%0, %1"
  1539. [(set_attr "type" "ffarith")])
  1540.  
  1541. (define_insn "absxf2"
  1542.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1543.     (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
  1544.   "ENABLE_XF_PATTERNS"
  1545.   "abs%?e\\t%0, %1"
  1546. [(set_attr "type" "ffarith")])
  1547.  
  1548. (define_insn "sqrtsf2"
  1549.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1550.     (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
  1551.   ""
  1552.   "sqt%?s\\t%0, %1"
  1553. [(set_attr "type" "float_em")])
  1554.  
  1555. (define_insn "sqrtdf2"
  1556.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1557.     (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
  1558.   ""
  1559.   "sqt%?d\\t%0, %1"
  1560. [(set_attr "type" "float_em")])
  1561.  
  1562. (define_insn ""
  1563.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1564.     (sqrt:DF (float_extend:DF
  1565.           (match_operand:SF 1 "s_register_operand" "f"))))]
  1566.   ""
  1567.   "sqt%?d\\t%0, %1"
  1568. [(set_attr "type" "float_em")])
  1569.  
  1570. (define_insn "sqrtxf2"
  1571.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1572.     (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
  1573.   "ENABLE_XF_PATTERNS"
  1574.   "sqt%?e\\t%0, %1"
  1575. [(set_attr "type" "float_em")])
  1576.  
  1577. (define_insn "sinsf2"
  1578.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1579.     (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))]
  1580.   ""
  1581.   "sin%?s\\t%0, %1"
  1582. [(set_attr "type" "float_em")])
  1583.  
  1584. (define_insn "sindf2"
  1585.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1586.     (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))]
  1587.   ""
  1588.   "sin%?d\\t%0, %1"
  1589. [(set_attr "type" "float_em")])
  1590.  
  1591. (define_insn ""
  1592.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1593.     (unspec:DF [(float_extend:DF
  1594.              (match_operand:SF 1 "s_register_operand" "f"))] 0))]
  1595.   ""
  1596.   "sin%?d\\t%0, %1"
  1597. [(set_attr "type" "float_em")])
  1598.  
  1599. (define_insn "sinxf2"
  1600.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1601.     (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))]
  1602.   "ENABLE_XF_PATTERNS"
  1603.   "sin%?e\\t%0, %1"
  1604. [(set_attr "type" "float_em")])
  1605.  
  1606. (define_insn "cossf2"
  1607.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1608.     (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))]
  1609.   ""
  1610.   "cos%?s\\t%0, %1"
  1611. [(set_attr "type" "float_em")])
  1612.  
  1613. (define_insn "cosdf2"
  1614.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1615.     (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))]
  1616.   ""
  1617.   "cos%?d\\t%0, %1"
  1618. [(set_attr "type" "float_em")])
  1619.  
  1620. (define_insn ""
  1621.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1622.     (unspec:DF [(float_extend:DF
  1623.              (match_operand:SF 1 "s_register_operand" "f"))] 1))]
  1624.   ""
  1625.   "cos%?d\\t%0, %1"
  1626. [(set_attr "type" "float_em")])
  1627.  
  1628. (define_insn "cosxf2"
  1629.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1630.     (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))]
  1631.   "ENABLE_XF_PATTERNS"
  1632.   "cos%?e\\t%0, %1"
  1633. [(set_attr "type" "float_em")])
  1634.  
  1635. (define_insn "one_cmpldi2"
  1636.   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
  1637.     (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
  1638.   ""
  1639.   "mvn%?\\t%0, %1\;mvn%?\\t%R0, %R1"
  1640. [(set_attr "length" "8")])
  1641.  
  1642. (define_insn "one_cmplsi2"
  1643.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1644.     (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
  1645.   ""
  1646.   "mvn%?\\t%0, %1")
  1647.  
  1648. (define_insn ""
  1649.   [(set (reg:CC_NOOV 24)
  1650.     (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
  1651.              (const_int 0)))
  1652.    (set (match_operand:SI 0 "s_register_operand" "=r")
  1653.     (not:SI (match_dup 1)))]
  1654.   ""
  1655.   "mvn%?s\\t%0, %1"
  1656. [(set_attr "conds" "set")])
  1657.  
  1658. (define_insn ""
  1659.   [(set (reg:CC_NOOV 24)
  1660.     (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
  1661.              (const_int 0)))
  1662.    (clobber (match_scratch:SI 0 "=r"))]
  1663.   ""
  1664.   "mvn%?s\\t%0, %1"
  1665. [(set_attr "conds" "set")])
  1666.  
  1667. ;; Fixed <--> Floating conversion insns
  1668.  
  1669. (define_insn "floatsisf2"
  1670.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1671.     (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
  1672.   ""
  1673.   "flt%?s\\t%0, %1"
  1674. [(set_attr "type" "r_2_f")])
  1675.  
  1676. (define_insn "floatsidf2"
  1677.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1678.     (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
  1679.   ""
  1680.   "flt%?d\\t%0, %1"
  1681. [(set_attr "type" "r_2_f")])
  1682.  
  1683. (define_insn "floatsixf2"
  1684.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1685.     (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
  1686.   "ENABLE_XF_PATTERNS"
  1687.   "flt%?e\\t%0, %1"
  1688. [(set_attr "type" "r_2_f")])
  1689.  
  1690. (define_insn "fix_truncsfsi2"
  1691.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1692.     (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
  1693.   ""
  1694.   "fix%?z\\t%0, %1"
  1695. [(set_attr "type" "f_2_r")])
  1696.  
  1697. (define_insn "fix_truncdfsi2"
  1698.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1699.     (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
  1700.   ""
  1701.   "fix%?z\\t%0, %1"
  1702. [(set_attr "type" "f_2_r")])
  1703.  
  1704. (define_insn "fix_truncxfsi2"
  1705.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1706.     (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
  1707.   "ENABLE_XF_PATTERNS"
  1708.   "fix%?z\\t%0, %1"
  1709. [(set_attr "type" "f_2_r")])
  1710.  
  1711. ;; Truncation insns
  1712.  
  1713. (define_insn "truncdfsf2"
  1714.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1715.     (float_truncate:SF
  1716.      (match_operand:DF 1 "s_register_operand" "f")))]
  1717.   ""
  1718.   "mvf%?s\\t%0, %1"
  1719. [(set_attr "type" "ffarith")])
  1720.  
  1721. (define_insn "truncxfsf2"
  1722.   [(set (match_operand:SF 0 "s_register_operand" "=f")
  1723.     (float_truncate:SF
  1724.      (match_operand:XF 1 "s_register_operand" "f")))]
  1725.   "ENABLE_XF_PATTERNS"
  1726.   "mvf%?s\\t%0, %1"
  1727. [(set_attr "type" "ffarith")])
  1728.  
  1729. (define_insn "truncxfdf2"
  1730.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1731.     (float_truncate:DF
  1732.      (match_operand:XF 1 "s_register_operand" "f")))]
  1733.   "ENABLE_XF_PATTERNS"
  1734.   "mvf%?d\\t%0, %1"
  1735. [(set_attr "type" "ffarith")])
  1736.  
  1737. ;; Zero and sign extension instructions.
  1738.  
  1739. (define_insn "zero_extendsidi2"
  1740.   [(set (match_operand:DI 0 "s_register_operand" "=r")
  1741.         (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
  1742.   ""
  1743.   "*
  1744.   if (REGNO (operands[1]) != REGNO (operands[0]))
  1745.     output_asm_insn (\"mov%?\\t%0, %1\", operands);
  1746.   return \"mov%?\\t%R0, #0\";
  1747. "
  1748. [(set_attr "length" "8")])
  1749.  
  1750. (define_insn "zero_extendqidi2"
  1751.   [(set (match_operand:DI 0 "s_register_operand" "=r,r")
  1752.     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
  1753.   ""
  1754.   "@
  1755.    and%?\\t%0, %1, #255\;mov%?\\t%R0, #0
  1756.    ldr%?b\\t%0, %1\;mov%?\\t%R0, #0"
  1757. [(set_attr "length" "8")
  1758.  (set_attr "type" "*,load")])
  1759.  
  1760. (define_insn "extendsidi2"
  1761.   [(set (match_operand:DI 0 "s_register_operand" "=r")
  1762.         (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
  1763.   ""
  1764.   "*
  1765.   if (REGNO (operands[1]) != REGNO (operands[0]))
  1766.     output_asm_insn (\"mov%?\\t%0, %1\", operands);
  1767.   return \"mov%?\\t%R0, %0, asr #31\";
  1768. "
  1769. [(set_attr "length" "8")])
  1770.  
  1771. (define_expand "zero_extendhisi2"
  1772.   [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
  1773.                  (const_int 16)))
  1774.    (set (match_operand:SI 0 "s_register_operand" "")
  1775.     (lshiftrt:SI (match_dup 2) (const_int 16)))]
  1776.   ""
  1777.   "
  1778. {
  1779.   if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
  1780.     {
  1781.       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
  1782.       DONE;
  1783.     }
  1784.   if (! s_register_operand (operands[1], HImode))
  1785.     operands[1] = copy_to_mode_reg (HImode, operands[1]);
  1786.   operands[1] = gen_lowpart (SImode, operands[1]);
  1787.   operands[2] = gen_reg_rtx (SImode); 
  1788. }")
  1789.  
  1790. (define_expand "zero_extendqisi2"
  1791.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  1792.     (zero_extend:SI
  1793.      (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
  1794.   ""
  1795.   "
  1796.   if (GET_CODE (operands[1]) != MEM)
  1797.     {
  1798.       emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]),
  1799.                  GEN_INT (255)));
  1800.       DONE;
  1801.     }
  1802. ")
  1803.  
  1804. (define_insn ""
  1805.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  1806.     (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
  1807.   ""
  1808.   "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
  1809. [(set_attr "type" "load")])
  1810.  
  1811. (define_split
  1812.   [(set (match_operand:SI 0 "s_register_operand" "")
  1813.     (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
  1814.    (clobber (match_operand:SI 2 "s_register_operand" ""))]
  1815.   "GET_CODE (operands[1]) != MEM"
  1816.   [(set (match_dup 2) (match_dup 1))
  1817.    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
  1818.   "")
  1819.  
  1820. (define_insn ""
  1821.   [(set (reg:CC_NOOV 24)
  1822.     (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r")
  1823.              (const_int 0)))]
  1824.   ""
  1825.   "tst\\t%0, #255"
  1826. [(set_attr "conds" "set")])
  1827.  
  1828. (define_expand "extendhisi2"
  1829.   [(set (match_dup 2)
  1830.     (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
  1831.            (const_int 16)))
  1832.    (set (match_operand:SI 0 "s_register_operand" "")
  1833.     (ashiftrt:SI (match_dup 2)
  1834.              (const_int 16)))]
  1835.   ""
  1836.   "
  1837.   if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
  1838.     {
  1839.       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
  1840.       DONE;
  1841.     }
  1842.   if (! s_register_operand (operands[1], HImode))
  1843.     operands[1] = copy_to_mode_reg (HImode, operands[1]);
  1844.   operands[1] = gen_lowpart (SImode, operands[1]);
  1845.   operands[2] = gen_reg_rtx (SImode);
  1846. }")
  1847.  
  1848. (define_expand "extendhisi2_mem"
  1849.   [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
  1850.    (set (match_dup 3)
  1851.     (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
  1852.    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
  1853.    (set (match_operand:SI 0 "" "")
  1854.     (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
  1855.   ""
  1856.   "
  1857.   operands[0] = gen_lowpart (SImode, operands[0]);
  1858.   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  1859.   operands[2] = gen_reg_rtx (SImode);
  1860.   operands[3] = gen_reg_rtx (SImode);
  1861.   operands[6] = gen_reg_rtx (SImode);
  1862.  
  1863.   if (BYTES_BIG_ENDIAN)
  1864.     {
  1865.       operands[4] = operands[2];
  1866.       operands[5] = operands[3];
  1867.     }
  1868.   else
  1869.     {
  1870.       operands[4] = operands[3];
  1871.       operands[5] = operands[2];
  1872.     }
  1873. ")
  1874.  
  1875. (define_expand "extendqihi2"
  1876.   [(set (match_dup 2)
  1877.     (ashift:SI (match_operand:QI 1 "s_register_operand" "")
  1878.            (const_int 24)))
  1879.    (set (match_operand:HI 0 "s_register_operand" "")
  1880.     (ashiftrt:SI (match_dup 2)
  1881.              (const_int 24)))]
  1882.   ""
  1883.   "
  1884. { operands[0] = gen_lowpart (SImode, operands[0]);
  1885.   operands[1] = gen_lowpart (SImode, operands[1]);
  1886.   operands[2] = gen_reg_rtx (SImode); }")
  1887.  
  1888. (define_expand "extendqisi2"
  1889.   [(set (match_dup 2)
  1890.     (ashift:SI (match_operand:QI 1 "s_register_operand" "")
  1891.            (const_int 24)))
  1892.    (set (match_operand:SI 0 "s_register_operand" "")
  1893.     (ashiftrt:SI (match_dup 2)
  1894.              (const_int 24)))]
  1895.   ""
  1896.   "
  1897. { operands[1] = gen_lowpart (SImode, operands[1]);
  1898.   operands[2] = gen_reg_rtx (SImode); }")
  1899.  
  1900. (define_insn "extendsfdf2"
  1901.   [(set (match_operand:DF 0 "s_register_operand" "=f")
  1902.     (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
  1903.   ""
  1904.   "mvf%?d\\t%0, %1"
  1905. [(set_attr "type" "ffarith")])
  1906.  
  1907. (define_insn "extendsfxf2"
  1908.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1909.     (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
  1910.   "ENABLE_XF_PATTERNS"
  1911.   "mvf%?e\\t%0, %1"
  1912. [(set_attr "type" "ffarith")])
  1913.  
  1914. (define_insn "extenddfxf2"
  1915.   [(set (match_operand:XF 0 "s_register_operand" "=f")
  1916.     (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
  1917.   "ENABLE_XF_PATTERNS"
  1918.   "mvf%?e\\t%0, %1"
  1919. [(set_attr "type" "ffarith")])
  1920.  
  1921.  
  1922. ;; Move insns (including loads and stores)
  1923.  
  1924. ;; XXX Just some ideas about movti.
  1925. ;; I don't think these are a good idea on the arm, there just aren't enough
  1926. ;; registers
  1927. ;;(define_expand "loadti"
  1928. ;;  [(set (match_operand:TI 0 "s_register_operand" "")
  1929. ;;    (mem:TI (match_operand:SI 1 "address_operand" "")))]
  1930. ;;  "" "")
  1931.  
  1932. ;;(define_expand "storeti"
  1933. ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
  1934. ;;    (match_operand:TI 1 "s_register_operand" ""))]
  1935. ;;  "" "")
  1936.  
  1937. ;;(define_expand "movti"
  1938. ;;  [(set (match_operand:TI 0 "general_operand" "")
  1939. ;;    (match_operand:TI 1 "general_operand" ""))]
  1940. ;;  ""
  1941. ;;  "
  1942. ;;{
  1943. ;;  rtx insn;
  1944. ;;
  1945. ;;  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  1946. ;;    operands[1] = copy_to_reg (operands[1]);
  1947. ;;  if (GET_CODE (operands[0]) == MEM)
  1948. ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
  1949. ;;  else if (GET_CODE (operands[1]) == MEM)
  1950. ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
  1951. ;;  else
  1952. ;;    FAIL;
  1953. ;;
  1954. ;;  emit_insn (insn);
  1955. ;;  DONE;
  1956. ;;}")
  1957.  
  1958. ;; Recognise garbage generated above.
  1959.  
  1960. ;;(define_insn ""
  1961. ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
  1962. ;;    (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
  1963. ;;  ""
  1964. ;;  "*
  1965. ;;  {
  1966. ;;    register mem = (which_alternative < 3);
  1967. ;;    register char *template;
  1968. ;;
  1969. ;;    operands[mem] = XEXP (operands[mem], 0);
  1970. ;;    switch (which_alternative)
  1971. ;;      {
  1972. ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
  1973. ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
  1974. ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
  1975. ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
  1976. ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
  1977. ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
  1978. ;;      }
  1979. ;;    output_asm_insn (template, operands);
  1980. ;;    return \"\";
  1981. ;;  }")
  1982.  
  1983.  
  1984. (define_insn "movdi"
  1985.   [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r")
  1986.     (match_operand:DI 1 "di_operand" "rIK,n,o<>,r,F"))]
  1987.   ""
  1988.   "*
  1989.   return (output_move_double (operands));
  1990. "
  1991. [(set_attr "length" "8,32,8,8,32")
  1992.  (set_attr "type" "*,*,load,store2,*")])
  1993.  
  1994. (define_expand "movsi"
  1995.   [(set (match_operand:SI 0 "general_operand" "")
  1996.         (match_operand:SI 1 "general_operand" ""))]
  1997.   ""
  1998.   "
  1999.   /* Everything except mem = const or mem = mem can be done easily */
  2000.   if (GET_CODE (operands[0]) == MEM)
  2001.     operands[1] = force_reg (SImode, operands[1]);
  2002.   if (GET_CODE (operands[1]) == CONST_INT
  2003.       && !(const_ok_for_arm (INTVAL (operands[1]))
  2004.            || const_ok_for_arm (~INTVAL (operands[1]))))
  2005.     {
  2006.       arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
  2007.               NULL_RTX,
  2008.               (reload_in_progress || reload_completed ? 0
  2009.                : preserve_subexpressions_p ()));
  2010.       DONE;
  2011.     }
  2012. ")
  2013.  
  2014. (define_insn ""
  2015.   [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,m,r,r")
  2016.     (match_operand:SI 1 "general_operand"  "R,m,K,rI,r,S,?n"))]
  2017.   "(register_operand (operands[0], SImode)
  2018.     && (GET_CODE (operands[1]) != SYMBOL_REF
  2019.     || CONSTANT_ADDRESS_P (operands[1])))
  2020.    || register_operand (operands[1], SImode)"
  2021.   "*
  2022.   switch (which_alternative)
  2023.     {
  2024.     case 0:
  2025.       /* NB Calling get_attr_length may cause the insn to be re-extracted... */
  2026.       if (get_attr_length (insn) == 8)
  2027.     {
  2028.       /* ... so modify the operands here.  */
  2029.       operands[1] = XEXP (operands[1], 0);
  2030.       output_asm_insn (\"sub%?\\t%0, %|pc, #(8 + . - %a1) & ~4095\",
  2031.                operands);
  2032.       output_asm_insn (\"ldr%?\\t%0, [%0, #- ((4 + . - %a1) & 4095)]\",
  2033.                operands);
  2034.     }
  2035.       else
  2036.     {
  2037.       /* ... and here.  */
  2038.       operands[1] = XEXP (operands[1], 0);
  2039.       output_asm_insn (\"ldr%?\\t%0, [%|pc, %1 - . - 8]\", operands);
  2040.     }
  2041.       return \"\";
  2042.  
  2043.     case 1:
  2044.       if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
  2045.       &&  CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
  2046.     abort ();
  2047.       return \"ldr%?\\t%0, %1\";
  2048.  
  2049.     case 3:
  2050.       return \"mov%?\\t%0, %1\";
  2051.     case 2:
  2052.       return \"mvn%?\\t%0, #%B1\";
  2053.     case 4:
  2054.       return \"str%?\\t%1, %0\";
  2055.     case 5:
  2056.       return output_load_symbol (insn, operands);
  2057.     case 6:
  2058.       return \"#\";
  2059.     }
  2060. "
  2061. [(set (attr "length")
  2062.       (cond [(eq_attr "alternative" "0")
  2063.              (if_then_else
  2064.               (gt (minus 
  2065.                    (pc)
  2066.                    (symbol_ref "const_pool_offset (XEXP (operands[1], 0))"))
  2067.                   (const_int 4087))
  2068.               (const_int 8)
  2069.               (const_int 4))
  2070.              (ior (eq_attr "alternative" "5")
  2071.           (eq_attr "alternative" "6")) (const_int 16)]
  2072.             (const_int 4)))
  2073.  (set_attr "type" "load,load,*,*,store1,*,*")])
  2074.  
  2075. (define_split
  2076.   [(set (match_operand:SI 0 "s_register_operand" "")
  2077.     (match_operand:SI 1 "const_int_operand" ""))]
  2078.   "! (const_ok_for_arm (INTVAL (operands[1]))
  2079.       || const_ok_for_arm (~INTVAL (operands[1])))"
  2080.   [(clobber (const_int 0))]
  2081.   "
  2082.   arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
  2083.               NULL_RTX, 0);
  2084.   DONE;
  2085. ")
  2086.  
  2087. ;; If copying one reg to another we can set the condition codes according to
  2088. ;; its value.  Such a move is common after a return from subroutine and the
  2089. ;; result is being tested against zero.
  2090.  
  2091. (define_insn ""
  2092.   [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "0,r")
  2093.                  (const_int 0)))
  2094.    (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))]
  2095.   ""
  2096.   "@
  2097.    cmp%?\\t%0, #0
  2098.    sub%?s\\t%0, %1, #0"
  2099. [(set_attr "conds" "set")])
  2100.  
  2101. ;; Subroutine to store a half word from a register into memory.
  2102. ;; Operand 0 is the source register (HImode)
  2103. ;; Operand 1 is the destination address in a register (SImode)
  2104.  
  2105. ;; In both this routine and the next, we must be careful not to spill
  2106. ;; a memory address of reg+large_const into a seperate PLUS insn, since this
  2107. ;; can generate unrecognizable rtl.
  2108.  
  2109. (define_expand "storehi"
  2110.   [;; store the low byte
  2111.    (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
  2112.    ;; extract the high byte
  2113.    (set (match_dup 2)
  2114.     (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
  2115.    ;; store the high byte
  2116.    (set (mem:QI (match_dup 4))
  2117.     (subreg:QI (match_dup 2) 0))]    ;explicit subreg safe
  2118.   ""
  2119.   "
  2120. {
  2121.   enum rtx_code code = GET_CODE (operands[1]);
  2122.  
  2123.   if ((code == PLUS || code == MINUS)
  2124.       && (GET_CODE (XEXP (operands[1], 1)) == REG
  2125.       || GET_CODE (XEXP (operands[1], 0)) != REG))
  2126.     operands[1] = force_reg (SImode, operands[1]);
  2127.   operands[4] = plus_constant (operands[1], 1);
  2128.   operands[3] = gen_lowpart (QImode, operands[0]);
  2129.   operands[0] = gen_lowpart (SImode, operands[0]);
  2130.   operands[2] = gen_reg_rtx (SImode); 
  2131. }
  2132. ")
  2133.  
  2134. (define_expand "storehi_bigend"
  2135.   [(set (mem:QI (match_dup 4)) (match_dup 3))
  2136.    (set (match_dup 2)
  2137.     (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
  2138.    (set (mem:QI (match_operand 1 "" ""))
  2139.     (subreg:QI (match_dup 2) 0))]
  2140.   ""
  2141.   "
  2142. {
  2143.   enum rtx_code code = GET_CODE (operands[1]);
  2144.   if ((code == PLUS || code == MINUS)
  2145.       && (GET_CODE (XEXP (operands[1], 1)) == REG
  2146.       || GET_CODE (XEXP (operands[1], 0)) != REG))
  2147.     operands[1] = force_reg (SImode, operands[1]);
  2148.  
  2149.   operands[4] = plus_constant (operands[1], 1);
  2150.   operands[3] = gen_lowpart (QImode, operands[0]);
  2151.   operands[0] = gen_lowpart (SImode, operands[0]);
  2152.   operands[2] = gen_reg_rtx (SImode);
  2153. }
  2154. ")
  2155.  
  2156. ;; Subroutine to store a half word integer constant into memory.
  2157. (define_expand "storeinthi"
  2158.   [(set (mem:QI (match_operand:SI 0 "" ""))
  2159.     (subreg:QI (match_operand 1 "" "") 0))
  2160.    (set (mem:QI (match_dup 3)) (subreg:QI (match_dup 2) 0))]
  2161.   ""
  2162.   "
  2163. {
  2164.   HOST_WIDE_INT value = INTVAL (operands[1]);
  2165.   enum rtx_code code = GET_CODE (operands[0]);
  2166.  
  2167.   if ((code == PLUS || code == MINUS)
  2168.       && (GET_CODE (XEXP (operands[0], 1)) == REG
  2169.       || GET_CODE (XEXP (operands[0], 0)) != REG))
  2170.   operands[0] = force_reg (SImode, operands[0]);
  2171.  
  2172.   operands[1] = gen_reg_rtx (SImode);
  2173.   if (BYTES_BIG_ENDIAN)
  2174.     {
  2175.       emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
  2176.       if ((value & 255) == ((value >> 8) & 255))
  2177.     operands[2] = operands[1];
  2178.       else
  2179.     {
  2180.       operands[2] = gen_reg_rtx (SImode);
  2181.       emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
  2182.     }
  2183.     }
  2184.   else
  2185.     {
  2186.       emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
  2187.       if ((value & 255) == ((value >> 8) & 255))
  2188.     operands[2] = operands[1];
  2189.       else
  2190.     {
  2191.       operands[2] = gen_reg_rtx (SImode);
  2192.       emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
  2193.     }
  2194.     }
  2195.  
  2196.   operands[3] = plus_constant (operands[0], 1);
  2197. }
  2198. ")
  2199.  
  2200. (define_expand "movhi"
  2201.   [(set (match_operand:HI 0 "general_operand" "")
  2202.     (match_operand:HI 1 "general_operand" ""))]
  2203.   ""
  2204.   "
  2205. {
  2206.   rtx insn;
  2207.  
  2208.   if (! (reload_in_progress || reload_completed))
  2209.     {
  2210.       if (GET_CODE (operands[0]) == MEM)
  2211.     {
  2212.       if (GET_CODE (operands[1]) == CONST_INT)
  2213.         emit_insn (gen_storeinthi (XEXP (operands[0], 0), operands[1]));
  2214.       else
  2215.         {
  2216.           if (GET_CODE (operands[1]) == MEM)
  2217.         operands[1] = force_reg (HImode, operands[1]);
  2218.           if (BYTES_BIG_ENDIAN)
  2219.         emit_insn (gen_storehi_bigend (operands[1],
  2220.                            XEXP (operands[0], 0)));
  2221.           else
  2222.         emit_insn (gen_storehi (operands[1], XEXP (operands[0], 0)));
  2223.         }
  2224.       DONE;
  2225.     }
  2226.       /* Sign extend a constant, and keep it in an SImode reg.  */
  2227.       else if (GET_CODE (operands[1]) == CONST_INT)
  2228.     {
  2229.       rtx reg = gen_reg_rtx (SImode);
  2230.       HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
  2231.  
  2232.       /* If the constant is already valid, leave it alone.  */
  2233.       if (! const_ok_for_arm (val))
  2234.         {
  2235.           /* If setting all the top bits will make the constant 
  2236.          loadable in a single instruction, then set them.  
  2237.          Otherwise, sign extend the number.  */
  2238.  
  2239.           if (const_ok_for_arm (~ (val | ~0xffff)))
  2240.         val |= ~0xffff;
  2241.           else if (val & 0x8000)
  2242.         val |= ~0xffff;
  2243.         }
  2244.  
  2245.       emit_insn (gen_movsi (reg, GEN_INT (val)));
  2246.       operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
  2247.     }
  2248.       else if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM)
  2249.         {
  2250.       rtx reg = gen_reg_rtx (SImode);
  2251.       emit_insn (gen_movhi_bytes (reg, operands[1]));
  2252.       operands[1] = gen_lowpart (HImode, reg);
  2253.     }
  2254.       else if (BYTES_BIG_ENDIAN && GET_CODE (operands[1]) == MEM)
  2255.     {
  2256.       emit_insn (gen_movhi_bigend (operands[0], operands[1]));
  2257.       DONE;
  2258.     }
  2259.     }
  2260. }
  2261. ")
  2262.  
  2263. (define_expand "movhi_bytes"
  2264.   [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" ""))))
  2265.    (set (match_dup 3)
  2266.     (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1)))))
  2267.    (set (match_operand:SI 0 "" "")
  2268.      (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
  2269.   ""
  2270.   "
  2271.   operands[0] = gen_lowpart (SImode, operands[0]);
  2272.   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  2273.   operands[2] = gen_reg_rtx (SImode);
  2274.   operands[3] = gen_reg_rtx (SImode);
  2275.  
  2276.   if (BYTES_BIG_ENDIAN)
  2277.     {
  2278.       operands[4] = operands[2];
  2279.       operands[5] = operands[3];
  2280.     }
  2281.   else
  2282.     {
  2283.       operands[4] = operands[3];
  2284.       operands[5] = operands[2];
  2285.     }
  2286. ")
  2287.  
  2288. (define_expand "movhi_bigend"
  2289.   [(set (match_dup 2)
  2290.     (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
  2291.            (const_int 16)))
  2292.    (set (match_dup 3)
  2293.     (ashiftrt:SI (match_dup 2) (const_int 16)))
  2294.    (set (match_operand:HI 0 "s_register_operand" "")
  2295.     (subreg:HI (match_dup 3) 0))]
  2296.   ""
  2297.   "
  2298.   operands[2] = gen_reg_rtx (SImode);
  2299.   operands[3] = gen_reg_rtx (SImode);
  2300. ")
  2301.  
  2302. ;; Pattern to recognise insn generated default case above
  2303.  
  2304. (define_insn ""
  2305.   [(set (match_operand:HI 0 "general_operand" "=r,r,r")
  2306.     (match_operand:HI 1 "general_operand"  "rI,K,m"))]
  2307.   "! BYTES_BIG_ENDIAN
  2308.    && ! TARGET_SHORT_BY_BYTES
  2309.    && (GET_CODE (operands[1]) != CONST_INT
  2310.        || const_ok_for_arm (INTVAL (operands[1]))
  2311.        || const_ok_for_arm (~INTVAL (operands[1])))"
  2312.   "@
  2313.    mov%?\\t%0, %1\\t%@ movhi
  2314.    mvn%?\\t%0, #%B1\\t%@ movhi
  2315.    ldr%?\\t%0, %1\\t%@ movhi"
  2316. [(set_attr "type" "*,*,load")])
  2317.  
  2318. (define_insn ""
  2319.   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
  2320.     (match_operand:HI 1 "general_operand"  "rI,K,m"))]
  2321.   "BYTES_BIG_ENDIAN
  2322.    && ! TARGET_SHORT_BY_BYTES
  2323.    && (GET_CODE (operands[1]) != CONST_INT
  2324.        || const_ok_for_arm (INTVAL (operands[1]))
  2325.        || const_ok_for_arm (~INTVAL (operands[1])))"
  2326.   "@
  2327.    mov%?\\t%0, %1\\t%@ movhi
  2328.    mvn%?\\t%0, #%B1\\t%@ movhi
  2329.    ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
  2330. [(set_attr "type" "*,*,load")
  2331.  (set_attr "length" "4,4,8")])
  2332.  
  2333. (define_insn ""
  2334.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  2335.     (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
  2336.            (const_int 16)))]
  2337.   "BYTES_BIG_ENDIAN
  2338.    && ! TARGET_SHORT_BY_BYTES"
  2339.   "ldr%?\\t%0, %1\\t%@ movhi_bigend"
  2340. [(set_attr "type" "load")])
  2341.  
  2342. (define_insn ""
  2343.   [(set (match_operand:HI 0 "s_register_operand" "=r,r")
  2344.     (match_operand:HI 1 "arm_rhs_operand"  "rI,K"))]
  2345.   "TARGET_SHORT_BY_BYTES"
  2346.   "@
  2347.    mov%?\\t%0, %1\\t%@ movhi
  2348.    mvn%?\\t%0, #%B1\\t%@ movhi")
  2349.  
  2350.  
  2351. (define_expand "reload_outhi"
  2352.   [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
  2353.           (match_operand:HI 1 "s_register_operand" "r")
  2354.           (match_operand:SI 2 "s_register_operand" "=&r")])]
  2355.   ""
  2356.   "
  2357.   arm_reload_out_hi (operands);
  2358.   DONE;
  2359. ")
  2360.  
  2361. (define_expand "reload_inhi"
  2362.   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
  2363.           (match_operand:HI 1 "reload_memory_operand" "o")
  2364.           (match_operand:SI 2 "s_register_operand" "=&r")])]
  2365.   "TARGET_SHORT_BY_BYTES"
  2366.   "
  2367.   arm_reload_in_hi (operands);
  2368.   DONE;
  2369. ")
  2370.  
  2371. (define_expand "movqi"
  2372.   [(set (match_operand:QI 0 "general_operand" "")
  2373.         (match_operand:QI 1 "general_operand" ""))]
  2374.   ""
  2375.   "
  2376.   /* Everything except mem = const or mem = mem can be done easily */
  2377.  
  2378.   if (!(reload_in_progress || reload_completed))
  2379.     {
  2380.       if (GET_CODE (operands[1]) == CONST_INT)
  2381.     {
  2382.       rtx reg = gen_reg_rtx (SImode);
  2383.  
  2384.       emit_insn (gen_movsi (reg, operands[1]));
  2385.       operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
  2386.     }
  2387.       if (GET_CODE (operands[0]) == MEM)
  2388.     operands[1] = force_reg (QImode, operands[1]);
  2389.     }
  2390. ")
  2391.  
  2392.  
  2393. (define_insn ""
  2394.   [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
  2395.     (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
  2396.   "register_operand (operands[0], QImode)
  2397.    || register_operand (operands[1], QImode)"
  2398.   "@
  2399.    mov%?\\t%0, %1
  2400.    mvn%?\\t%0, #%B1
  2401.    ldr%?b\\t%0, %1
  2402.    str%?b\\t%1, %0"
  2403. [(set_attr "type" "*,*,load,store1")])
  2404.  
  2405. (define_expand "movsf"
  2406.   [(set (match_operand:SF 0 "general_operand" "")
  2407.     (match_operand:SF 1 "general_operand" ""))]
  2408.   ""
  2409.   "
  2410.   if (GET_CODE (operands[1]) == CONST_DOUBLE
  2411.       && ((GET_CODE (operands[0]) == REG
  2412.        && REGNO (operands[0]) < 16)
  2413.       || ! (const_double_rtx_ok_for_fpu (operands[1])
  2414.         || neg_const_double_rtx_ok_for_fpu (operands[1]))))
  2415.     {
  2416.       extern int optimize;
  2417.       rtx mem = force_const_mem (SFmode, operands[1]);
  2418.       rtx addr;
  2419.  
  2420.       if (reload_in_progress || reload_completed)
  2421.     addr = gen_rtx (REG, SImode, REGNO (operands[0]));
  2422.       else
  2423.         addr = gen_reg_rtx (SImode);
  2424.       if (optimize == 0)
  2425.     {
  2426.       rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
  2427.       emit_insn (gen_movsi (addr, ptr));
  2428.     }
  2429.       else
  2430.     emit_insn (gen_movsi (addr, XEXP (mem, 0)));
  2431.       operands[1] = gen_rtx (MEM, SFmode, addr);
  2432.     }
  2433.   if (GET_CODE (operands[0]) == MEM)
  2434.     operands[1] = force_reg (SFmode, operands[1]);
  2435. ")
  2436.  
  2437. (define_insn ""
  2438.   [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m")
  2439.     (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))]
  2440.   "GET_CODE (operands[0]) != MEM || register_operand (operands[1], SFmode)"
  2441.   "@
  2442.    mvf%?s\\t%0, %1
  2443.    mnf%?s\\t%0, #%N1
  2444.    ldf%?s\\t%0, %1
  2445.    stf%?s\\t%1, %0
  2446.    str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
  2447.    stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
  2448.    mov%?\\t%0, %1
  2449.    ldr%?\\t%0, %1\\t%@ float
  2450.    str%?\\t%1, %0\\t%@ float"
  2451. [(set_attr "length" "4,4,4,4,8,8,4,4,4")
  2452.  (set_attr "type"
  2453.      "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")])
  2454.  
  2455. (define_expand "movdf"
  2456.   [(set (match_operand:DF 0 "general_operand" "")
  2457.     (match_operand:DF 1 "general_operand" ""))]
  2458.   ""
  2459.   "
  2460.   if (GET_CODE (operands[1]) == CONST_DOUBLE
  2461.       && ((GET_CODE (operands[0]) == REG
  2462.        && REGNO (operands[0]) < 16)
  2463.       || ! (const_double_rtx_ok_for_fpu (operands[1])
  2464.         || neg_const_double_rtx_ok_for_fpu (operands[1]))))
  2465.     {
  2466.       extern int optimize;
  2467.       rtx mem = force_const_mem (DFmode, operands[1]);
  2468.       rtx addr;
  2469.  
  2470.       if (reload_in_progress || reload_completed)
  2471.     addr = gen_rtx (REG, SImode, REGNO (operands[0]));
  2472.       else
  2473.     addr = gen_reg_rtx (SImode);
  2474.       if (optimize == 0)
  2475.     {
  2476.       rtx ptr = force_const_mem (SImode, XEXP (mem, 0));
  2477.       emit_insn (gen_movsi (addr, ptr));
  2478.     }
  2479.       else
  2480.     emit_insn (gen_movsi (addr, XEXP (mem, 0)));
  2481.       operands[1] = gen_rtx (MEM, DFmode, addr);
  2482.     }
  2483.   if (GET_CODE (operands[0]) == MEM)
  2484.     operands[1] = force_reg (DFmode, operands[1]);
  2485. ")
  2486.  
  2487. ;; Reloading a df mode value stored in integer regs to memory can require a
  2488. ;; scratch reg.
  2489. (define_expand "reload_outdf"
  2490.   [(match_operand:DF 0 "reload_memory_operand" "=o")
  2491.    (match_operand:DF 1 "s_register_operand" "r")
  2492.    (match_operand:SI 2 "s_register_operand" "=&r")]
  2493.   ""
  2494.   "
  2495.   if (GET_CODE (XEXP (operands[0], 0)) == REG)
  2496.     operands[2] = XEXP (operands[0], 0);
  2497.   else
  2498.     emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
  2499.                XEXP (XEXP (operands[0], 0), 1)));
  2500.   emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, DFmode, operands[2]),
  2501.               operands[1]));
  2502.   DONE;
  2503. ")
  2504.  
  2505. (define_insn ""
  2506.   [(set (match_operand:DF 0 "general_operand" "=r,Q#m,r,f,f,f,f,m,!f,!r,r")
  2507.     (match_operand:DF 1 "general_operand" 
  2508.          "Q,r,?o,?f,!G,!H,m,f,r,f,??r"))]
  2509.   "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)"
  2510.   "*
  2511. {
  2512.   rtx ops[3];
  2513.  
  2514.   switch (which_alternative)
  2515.     {
  2516.     case 0:
  2517.       return \"ldm%?ia\\t%m1, {%0, %R0}\\t%@ double\";
  2518.  
  2519.     case 1:
  2520.       return \"stm%?ia\\t%m0, {%1, %R1}\\t%@ double\";
  2521.  
  2522.     case 2:
  2523.       ops[0] = operands[0];
  2524.       ops[1] = XEXP (XEXP (operands[1], 0), 0);
  2525.       ops[2] = XEXP (XEXP (operands[1], 0), 1);
  2526.       if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2])))
  2527.     output_asm_insn (\"add%?\\t%0, %1, %2\", ops);
  2528.       else
  2529.     output_asm_insn (\"sub%?\\t%0, %1, #%n2\", ops);
  2530.       return \"ldm%?ia\\t%0, {%0, %R0}\\t%@ double\";
  2531.  
  2532.     case 3:
  2533.     case 4:
  2534.       return \"mvf%?d\\t%0, %1\";
  2535.  
  2536.     case 5: return \"mnf%?d\\t%0, #%N1\";
  2537.     case 6: return \"ldf%?d\\t%0, %1\";
  2538.     case 7: return \"stf%?d\\t%1, %0\";
  2539.     case 8: return output_mov_double_fpu_from_arm (operands);
  2540.     case 9: return output_mov_double_arm_from_fpu (operands);
  2541.     case 10: return output_move_double (operands);
  2542.     }
  2543. }
  2544. "
  2545. [(set_attr "length" "4,4,8,4,4,4,4,4,8,8,8")
  2546.  (set_attr "type" 
  2547. "load,store2,load,ffarith,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
  2548.  
  2549. (define_expand "movxf"
  2550.   [(set (match_operand:XF 0 "general_operand" "")
  2551.     (match_operand:XF 1 "general_operand" ""))]
  2552.   "ENABLE_XF_PATTERNS"
  2553.   "")
  2554.  
  2555. ;; Even when the XFmode patterns aren't enabled, we enable this after
  2556. ;; reloading so that we can push floating point registers in the prologue.
  2557.  
  2558. (define_insn ""
  2559.   [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r")
  2560.     (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
  2561.   "ENABLE_XF_PATTERNS || reload_completed"
  2562.   "*
  2563.   switch (which_alternative)
  2564.     {
  2565.     case 0: return \"mvf%?e\\t%0, %1\";
  2566.     case 1: return \"mnf%?e\\t%0, #%N1\";
  2567.     case 2: return \"ldf%?e\\t%0, %1\";
  2568.     case 3: return \"stf%?e\\t%1, %0\";
  2569.     case 4: return output_mov_long_double_fpu_from_arm (operands);
  2570.     case 5: return output_mov_long_double_arm_from_fpu (operands);
  2571.     case 6: return output_mov_long_double_arm_from_arm (operands);
  2572.     }
  2573. "
  2574. [(set_attr "length" "4,4,4,4,8,8,12")
  2575.  (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")])
  2576.  
  2577.  
  2578. ;; load- and store-multiple insns
  2579. ;; The arm can load/store any set of registers, provided that they are in
  2580. ;; ascending order; but that is beyond GCC so stick with what it knows.
  2581.  
  2582. (define_expand "load_multiple"
  2583.   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
  2584.                           (match_operand:SI 1 "" ""))
  2585.                      (use (match_operand:SI 2 "" ""))])]
  2586.   ""
  2587.   "
  2588.   /* Support only fixed point registers */
  2589.   if (GET_CODE (operands[2]) != CONST_INT
  2590.       || INTVAL (operands[2]) > 14
  2591.       || INTVAL (operands[2]) < 2
  2592.       || GET_CODE (operands[1]) != MEM
  2593.       || GET_CODE (operands[0]) != REG
  2594.       || REGNO (operands[0]) > 14
  2595.       || REGNO (operands[0]) + INTVAL (operands[2]) > 15)
  2596.     FAIL;
  2597.  
  2598.   operands[3]
  2599.             = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
  2600.                                      force_reg (SImode, XEXP (operands[1], 0)),
  2601.                                      TRUE, FALSE);
  2602. ")
  2603.  
  2604. ;; Load multiple with write-back
  2605.  
  2606. (define_insn ""
  2607.   [(match_parallel 0 "load_multiple_operation"
  2608.                    [(set (match_operand:SI 1 "s_register_operand" "+r")
  2609.                          (plus:SI (match_dup 1)
  2610.                                   (match_operand:SI 2 "immediate_operand" "n")))
  2611.                     (set (match_operand:SI 3 "s_register_operand" "=r")
  2612.                          (mem:SI (match_dup 1)))])]
  2613.   "(INTVAL (operands[2])  == 4 * (XVECLEN (operands[0], 0) - 2))"
  2614.   "*
  2615. {
  2616.   rtx ops[3];
  2617.   int count = XVECLEN (operands[0], 0);
  2618.  
  2619.   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
  2620.   ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
  2621.   ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2));
  2622.  
  2623.   output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
  2624.   return \"\";
  2625. }
  2626. "
  2627. [(set_attr "type" "load")])
  2628.  
  2629. ;; Ordinary load multiple
  2630.  
  2631. (define_insn ""
  2632.   [(match_parallel 0 "load_multiple_operation"
  2633.                    [(set (match_operand:SI 1 "s_register_operand" "=r")
  2634.                          (match_operand:SI 2 "indirect_operand" "Q"))])]
  2635.   ""
  2636.   "*
  2637. {
  2638.   rtx ops[3];
  2639.   int count = XVECLEN (operands[0], 0);
  2640.  
  2641.   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
  2642.   ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
  2643.   ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
  2644.  
  2645.   output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
  2646.   return \"\";
  2647. }
  2648. "
  2649. [(set_attr "type" "load")])
  2650.  
  2651. (define_expand "store_multiple"
  2652.   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
  2653.                           (match_operand:SI 1 "" ""))
  2654.                      (use (match_operand:SI 2 "" ""))])]
  2655.   ""
  2656.   "
  2657.   /* Support only fixed point registers */
  2658.   if (GET_CODE (operands[2]) != CONST_INT
  2659.       || INTVAL (operands[2]) > 14
  2660.       || INTVAL (operands[2]) < 2
  2661.       || GET_CODE (operands[1]) != REG
  2662.       || GET_CODE (operands[0]) != MEM
  2663.       || REGNO (operands[1]) > 14
  2664.       || REGNO (operands[1]) + INTVAL (operands[2]) > 15)
  2665.     FAIL;
  2666.  
  2667.   operands[3]
  2668.            = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
  2669.                                      force_reg (SImode, XEXP (operands[0], 0)),
  2670.                                      TRUE, FALSE);
  2671. ")
  2672.  
  2673. ;; Store multiple with write-back
  2674.  
  2675. (define_insn ""
  2676.   [(match_parallel 0 "store_multiple_operation"
  2677.                    [(set (match_operand:SI 1 "s_register_operand" "+r")
  2678.                          (plus:SI (match_dup 1)
  2679.                                   (match_operand:SI 2 "immediate_operand" "n")))
  2680.                     (set (mem:SI (match_dup 1))
  2681.                          (match_operand:SI 3 "s_register_operand" "r"))])]
  2682.   "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))"
  2683.   "*
  2684. {
  2685.   rtx ops[3];
  2686.   int count = XVECLEN (operands[0], 0);
  2687.  
  2688.   ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
  2689.   ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
  2690.   ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2));
  2691.  
  2692.   output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
  2693.   return \"\";
  2694. }
  2695. "
  2696. [(set (attr "type")
  2697.       (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
  2698.         (const_string "store2")
  2699.          (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5))
  2700.         (const_string "store3")]
  2701.       (const_string "store4")))])
  2702.  
  2703. ;; Ordinary store multiple
  2704.  
  2705. (define_insn ""
  2706.   [(match_parallel 0 "store_multiple_operation"
  2707.                    [(set (match_operand:SI 2 "indirect_operand" "=Q")
  2708.                          (match_operand:SI 1 "s_register_operand" "r"))])]
  2709.   ""
  2710.   "*
  2711. {
  2712.   rtx ops[3];
  2713.   int count = XVECLEN (operands[0], 0);
  2714.  
  2715.   ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
  2716.   ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
  2717.   ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
  2718.  
  2719.   output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
  2720.   return \"\";
  2721. }
  2722. "
  2723. [(set (attr "type")
  2724.       (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
  2725.         (const_string "store2")
  2726.          (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
  2727.         (const_string "store3")]
  2728.       (const_string "store4")))])
  2729.  
  2730. ;; Move a block of memory if it is word aligned and MORE than 2 words long.
  2731. ;; We could let this apply for blocks of less than this, but it clobbers so
  2732. ;; many registers that there is then probably a better way.
  2733.  
  2734. (define_expand "movstrqi"
  2735.   [(match_operand:BLK 0 "general_operand" "")
  2736.    (match_operand:BLK 1 "general_operand" "")
  2737.    (match_operand:SI 2 "const_int_operand" "")
  2738.    (match_operand:SI 3 "const_int_operand" "")]
  2739.   ""
  2740.   "
  2741.   if (arm_gen_movstrqi (operands))
  2742.     DONE;
  2743.   FAIL;
  2744. ")
  2745.  
  2746.  
  2747. ;; Comparison and test insns
  2748.  
  2749. (define_expand "cmpsi"
  2750.   [(set (reg:CC 24)
  2751.     (compare:CC (match_operand:SI 0 "s_register_operand" "")
  2752.                (match_operand:SI 1 "arm_add_operand" "")))]
  2753.   ""
  2754.   "
  2755. {
  2756.   arm_compare_op0 = operands[0];
  2757.   arm_compare_op1 = operands[1];
  2758.   arm_compare_fp = 0;
  2759.   DONE;
  2760. }
  2761. ")
  2762.  
  2763. (define_expand "cmpsf"
  2764.   [(set (reg:CC 24)
  2765.     (compare:CC (match_operand:SF 0 "s_register_operand" "")
  2766.             (match_operand:SF 1 "fpu_rhs_operand" "")))]
  2767.   ""
  2768.   "
  2769. {
  2770.   arm_compare_op0 = operands[0];
  2771.   arm_compare_op1 = operands[1];
  2772.   arm_compare_fp = 1;
  2773.   DONE;
  2774. }
  2775. ")
  2776.  
  2777. (define_expand "cmpdf"
  2778.   [(set (reg:CC 24)
  2779.     (compare:CC (match_operand:DF 0 "s_register_operand" "")
  2780.             (match_operand:DF 1 "fpu_rhs_operand" "")))]
  2781.   ""
  2782.   "
  2783. {
  2784.   arm_compare_op0 = operands[0];
  2785.   arm_compare_op1 = operands[1];
  2786.   arm_compare_fp = 1;
  2787.   DONE;
  2788. }
  2789. ")
  2790.  
  2791. (define_expand "cmpxf"
  2792.   [(set (reg:CC 24)
  2793.     (compare:CC (match_operand:XF 0 "s_register_operand" "")
  2794.             (match_operand:XF 1 "fpu_rhs_operand" "")))]
  2795.   "ENABLE_XF_PATTERNS"
  2796.   "
  2797. {
  2798.   arm_compare_op0 = operands[0];
  2799.   arm_compare_op1 = operands[1];
  2800.   arm_compare_fp = 1;
  2801.   DONE;
  2802. }
  2803. ")
  2804.  
  2805. (define_insn ""
  2806.   [(set (match_operand 0 "cc_register" "")
  2807.     (compare (match_operand:SI 1 "s_register_operand" "r,r")
  2808.          (match_operand:SI 2 "arm_add_operand" "rI,L")))]
  2809.   ""
  2810.   "@
  2811.    cmp%?\\t%1, %2
  2812.    cmn%?\\t%1, #%n2"
  2813. [(set_attr "conds" "set")])
  2814.  
  2815. (define_insn ""
  2816.   [(set (match_operand 0 "cc_register" "")
  2817.     (compare (match_operand:SI 1 "s_register_operand" "r")
  2818.          (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))]
  2819.   ""
  2820.   "cmn%?\\t%1, %2"
  2821. [(set_attr "conds" "set")])
  2822.  
  2823. (define_insn ""
  2824.   [(set (match_operand 0 "cc_register" "")
  2825.     (compare (match_operand:SI 1 "s_register_operand" "r")
  2826.          (match_operator:SI 2 "shift_operator"
  2827.           [(match_operand:SI 3 "s_register_operand" "r")
  2828.            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
  2829.   ""
  2830.   "cmp%?\\t%1, %3%S2"
  2831. [(set_attr "conds" "set")])
  2832.  
  2833. (define_insn ""
  2834.   [(set (match_operand 0 "cc_register" "")
  2835.     (compare (match_operand:SI 1 "s_register_operand" "r")
  2836.          (neg:SI (match_operator:SI 2 "shift_operator"
  2837.               [(match_operand:SI 3 "s_register_operand" "r")
  2838.                (match_operand:SI 4 "arm_rhs_operand" "rM")]))))]
  2839.   ""
  2840.   "cmn%?\\t%1, %3%S2"
  2841. [(set_attr "conds" "set")])
  2842.  
  2843. (define_insn ""
  2844.   [(set (reg:CCFP 24)
  2845.     (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
  2846.               (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
  2847.   ""
  2848.   "@
  2849.    cmf%?\\t%0, %1
  2850.    cnf%?\\t%0, #%N1"
  2851. [(set_attr "conds" "set")
  2852.  (set_attr "type" "f_2_r")])
  2853.  
  2854. (define_insn ""
  2855.   [(set (reg:CCFP 24)
  2856.     (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
  2857.               (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
  2858.   ""
  2859.   "@
  2860.    cmf%?\\t%0, %1
  2861.    cnf%?\\t%0, #%N1"
  2862. [(set_attr "conds" "set")
  2863.  (set_attr "type" "f_2_r")])
  2864.  
  2865. (define_insn ""
  2866.   [(set (reg:CCFP 24)
  2867.     (compare:CCFP (float_extend:DF
  2868.                (match_operand:SF 0 "s_register_operand" "f,f"))
  2869.               (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
  2870.   ""
  2871.   "@
  2872.    cmf%?\\t%0, %1
  2873.    cnf%?\\t%0, #%N1"
  2874. [(set_attr "conds" "set")
  2875.  (set_attr "type" "f_2_r")])
  2876.  
  2877. (define_insn ""
  2878.   [(set (reg:CCFP 24)
  2879.     (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
  2880.               (float_extend:DF
  2881.                (match_operand:SF 1 "s_register_operand" "f"))))]
  2882.   ""
  2883.   "cmf%?\\t%0, %1"
  2884. [(set_attr "conds" "set")
  2885.  (set_attr "type" "f_2_r")])
  2886.  
  2887. (define_insn ""
  2888.   [(set (reg:CCFP 24)
  2889.     (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
  2890.               (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
  2891.   "ENABLE_XF_PATTERNS"
  2892.   "@
  2893.    cmf%?\\t%0, %1
  2894.    cnf%?\\t%0, #%N1"
  2895. [(set_attr "conds" "set")
  2896.  (set_attr "type" "f_2_r")])
  2897.  
  2898. (define_insn ""
  2899.   [(set (reg:CCFPE 24)
  2900.     (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
  2901.                (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
  2902.   ""
  2903.   "@
  2904.    cmf%?e\\t%0, %1
  2905.    cnf%?e\\t%0, #%N1"
  2906. [(set_attr "conds" "set")
  2907.  (set_attr "type" "f_2_r")])
  2908.  
  2909. (define_insn ""
  2910.   [(set (reg:CCFPE 24)
  2911.     (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
  2912.                (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
  2913.   ""
  2914.   "@
  2915.    cmf%?e\\t%0, %1
  2916.    cnf%?e\\t%0, #%N1"
  2917. [(set_attr "conds" "set")
  2918.  (set_attr "type" "f_2_r")])
  2919.  
  2920. (define_insn ""
  2921.   [(set (reg:CCFPE 24)
  2922.     (compare:CCFPE (float_extend:DF
  2923.             (match_operand:SF 0 "s_register_operand" "f,f"))
  2924.                (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
  2925.   ""
  2926.   "@
  2927.    cmf%?e\\t%0, %1
  2928.    cnf%?e\\t%0, #%N1"
  2929. [(set_attr "conds" "set")
  2930.  (set_attr "type" "f_2_r")])
  2931.  
  2932. (define_insn ""
  2933.   [(set (reg:CCFPE 24)
  2934.     (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
  2935.                (float_extend:DF
  2936.             (match_operand:SF 1 "s_register_operand" "f"))))]
  2937.   ""
  2938.   "cmf%?e\\t%0, %1"
  2939. [(set_attr "conds" "set")
  2940.  (set_attr "type" "f_2_r")])
  2941.  
  2942. (define_insn ""
  2943.   [(set (reg:CCFPE 24)
  2944.     (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
  2945.                (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
  2946.   "ENABLE_XF_PATTERNS"
  2947.   "@
  2948.    cmf%?e\\t%0, %1
  2949.    cnf%?e\\t%0, #%N1"
  2950. [(set_attr "conds" "set")
  2951.  (set_attr "type" "f_2_r")])
  2952.  
  2953. ; This insn allows redundant compares to be removed by cse, nothing should
  2954. ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
  2955. ; is deleted later on. The match_dup will match the mode here, so that
  2956. ; mode changes of the condition codes aren't lost by this even though we don't
  2957. ; specify what they are.
  2958.  
  2959. (define_insn ""
  2960.   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
  2961.   ""
  2962.   "\\t%@ deleted compare"
  2963. [(set_attr "conds" "set")
  2964.  (set_attr "length" "0")])
  2965.  
  2966.  
  2967. ;; Conditional branch insns
  2968.  
  2969. (define_expand "beq"
  2970.   [(set (pc)
  2971.     (if_then_else (eq (match_dup 1) (const_int 0))
  2972.               (label_ref (match_operand 0 "" ""))
  2973.               (pc)))]
  2974.   ""
  2975.   "
  2976. {
  2977.   operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
  2978.                  arm_compare_fp);
  2979. }
  2980. ")
  2981.  
  2982. (define_expand "bne"
  2983.   [(set (pc)
  2984.     (if_then_else (ne (match_dup 1) (const_int 0))
  2985.               (label_ref (match_operand 0 "" ""))
  2986.               (pc)))]
  2987.   ""
  2988.   "
  2989. {
  2990.   operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
  2991.                  arm_compare_fp);
  2992. }
  2993. ")
  2994.  
  2995. (define_expand "bgt"
  2996.   [(set (pc)
  2997.     (if_then_else (gt (match_dup 1) (const_int 0))
  2998.               (label_ref (match_operand 0 "" ""))
  2999.               (pc)))]
  3000.   ""
  3001.   "
  3002. {
  3003.   operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
  3004.                  arm_compare_fp);
  3005. }
  3006. ")
  3007.  
  3008. (define_expand "ble"
  3009.   [(set (pc)
  3010.     (if_then_else (le (match_dup 1) (const_int 0))
  3011.               (label_ref (match_operand 0 "" ""))
  3012.               (pc)))]
  3013.   ""
  3014.   "
  3015. {
  3016.   operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
  3017.                  arm_compare_fp);
  3018. }
  3019. ")
  3020.  
  3021. (define_expand "bge"
  3022.   [(set (pc)
  3023.     (if_then_else (ge (match_dup 1) (const_int 0))
  3024.               (label_ref (match_operand 0 "" ""))
  3025.               (pc)))]
  3026.   ""
  3027.   "
  3028. {
  3029.   operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
  3030.                  arm_compare_fp);
  3031. }
  3032. ")
  3033.  
  3034. (define_expand "blt"
  3035.   [(set (pc)
  3036.     (if_then_else (lt (match_dup 1) (const_int 0))
  3037.               (label_ref (match_operand 0 "" ""))
  3038.               (pc)))]
  3039.   ""
  3040.   "
  3041. {
  3042.   operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
  3043.                  arm_compare_fp);
  3044. }
  3045. ")
  3046.  
  3047. (define_expand "bgtu"
  3048.   [(set (pc)
  3049.     (if_then_else (gtu (match_dup 1) (const_int 0))
  3050.               (label_ref (match_operand 0 "" ""))
  3051.               (pc)))]
  3052.   ""
  3053.   "
  3054. {
  3055.   operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
  3056.                  arm_compare_fp);
  3057. }
  3058. ")
  3059.  
  3060. (define_expand "bleu"
  3061.   [(set (pc)
  3062.     (if_then_else (leu (match_dup 1) (const_int 0))
  3063.               (label_ref (match_operand 0 "" ""))
  3064.               (pc)))]
  3065.   ""
  3066.   "
  3067. {
  3068.   operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
  3069.                  arm_compare_fp);
  3070. }
  3071. ")
  3072.  
  3073. (define_expand "bgeu"
  3074.   [(set (pc)
  3075.     (if_then_else (geu (match_dup 1) (const_int 0))
  3076.               (label_ref (match_operand 0 "" ""))
  3077.               (pc)))]
  3078.   ""
  3079.   "
  3080. {
  3081.   operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
  3082.                  arm_compare_fp);
  3083. }
  3084. ")
  3085.  
  3086. (define_expand "bltu"
  3087.   [(set (pc)
  3088.     (if_then_else (ltu (match_dup 1) (const_int 0))
  3089.               (label_ref (match_operand 0 "" ""))
  3090.               (pc)))]
  3091.   ""
  3092.   "
  3093. {
  3094.   operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
  3095.                  arm_compare_fp);
  3096. }
  3097. ")
  3098.  
  3099. ;; patterns to match conditional branch insns
  3100.  
  3101. (define_insn ""
  3102.   [(set (pc)
  3103.     (if_then_else (match_operator 1 "comparison_operator"
  3104.                     [(reg 24) (const_int 0)])
  3105.               (label_ref (match_operand 0 "" ""))
  3106.               (pc)))]
  3107.   ""
  3108.   "*
  3109. {
  3110.   extern int arm_ccfsm_state;
  3111.  
  3112.   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
  3113.   {
  3114.     arm_ccfsm_state += 2;
  3115.     return \"\";
  3116.   }
  3117.   return \"b%d1\\t%l0\";
  3118. }"
  3119. [(set_attr "conds" "use")])
  3120.  
  3121. (define_insn ""
  3122.   [(set (pc)
  3123.     (if_then_else (match_operator 1 "comparison_operator"
  3124.                     [(reg 24) (const_int 0)])
  3125.               (pc)
  3126.               (label_ref (match_operand 0 "" ""))))]
  3127.   "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
  3128.   "*
  3129. {
  3130.   extern int arm_ccfsm_state;
  3131.  
  3132.   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
  3133.   {
  3134.     arm_ccfsm_state += 2;
  3135.     return \"\";
  3136.   }
  3137.   return \"b%D1\\t%l0\";
  3138. }"
  3139. [(set_attr "conds" "use")])
  3140.  
  3141.  
  3142. ; scc insns
  3143.  
  3144. (define_expand "seq"
  3145.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3146.     (eq:SI (match_dup 1) (const_int 0)))]
  3147.   ""
  3148.   "
  3149. {
  3150.   operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1,
  3151.                  arm_compare_fp);
  3152. }
  3153. ")
  3154.  
  3155. (define_expand "sne"
  3156.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3157.     (ne:SI (match_dup 1) (const_int 0)))]
  3158.   ""
  3159.   "
  3160. {
  3161.   operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1,
  3162.                  arm_compare_fp);
  3163. }
  3164. ")
  3165.  
  3166. (define_expand "sgt"
  3167.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3168.     (gt:SI (match_dup 1) (const_int 0)))]
  3169.   ""
  3170.   "
  3171. {
  3172.   operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1,
  3173.                  arm_compare_fp);
  3174. }
  3175. ")
  3176.  
  3177. (define_expand "sle"
  3178.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3179.     (le:SI (match_dup 1) (const_int 0)))]
  3180.   ""
  3181.   "
  3182. {
  3183.   operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1,
  3184.                  arm_compare_fp);
  3185. }
  3186. ")
  3187.  
  3188. (define_expand "sge"
  3189.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3190.     (ge:SI (match_dup 1) (const_int 0)))]
  3191.   ""
  3192.   "
  3193. {
  3194.   operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1,
  3195.                  arm_compare_fp);
  3196. }
  3197. ")
  3198.  
  3199. (define_expand "slt"
  3200.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3201.     (lt:SI (match_dup 1) (const_int 0)))]
  3202.   ""
  3203.   "
  3204. {
  3205.   operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1,
  3206.                  arm_compare_fp);
  3207. }
  3208. ")
  3209.  
  3210. (define_expand "sgtu"
  3211.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3212.     (gtu:SI (match_dup 1) (const_int 0)))]
  3213.   ""
  3214.   "
  3215. {
  3216.   operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1,
  3217.                  arm_compare_fp);
  3218. }
  3219. ")
  3220.  
  3221. (define_expand "sleu"
  3222.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3223.     (leu:SI (match_dup 1) (const_int 0)))]
  3224.   ""
  3225.   "
  3226. {
  3227.   operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1,
  3228.                  arm_compare_fp);
  3229. }
  3230. ")
  3231.  
  3232. (define_expand "sgeu"
  3233.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3234.     (geu:SI (match_dup 1) (const_int 0)))]
  3235.   ""
  3236.   "
  3237. {
  3238.   operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1,
  3239.                  arm_compare_fp);
  3240. }
  3241. ")
  3242.  
  3243. (define_expand "sltu"
  3244.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3245.     (ltu:SI (match_dup 1) (const_int 0)))]
  3246.   ""
  3247.   "
  3248. {
  3249.   operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1,
  3250.                  arm_compare_fp);
  3251. }
  3252. ")
  3253.  
  3254. (define_insn ""
  3255.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3256.     (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))]
  3257.   ""
  3258.   "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
  3259. [(set_attr "conds" "use")
  3260.  (set_attr "length" "8")])
  3261.  
  3262. (define_insn ""
  3263.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3264.     (neg:SI (match_operator:SI 1 "comparison_operator"
  3265.          [(reg 24) (const_int 0)])))]
  3266.   ""
  3267.   "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
  3268. [(set_attr "conds" "use")
  3269.  (set_attr "length" "8")])
  3270.  
  3271. (define_insn ""
  3272.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3273.     (not:SI (match_operator:SI 1 "comparison_operator"
  3274.          [(reg 24) (const_int 0)])))]
  3275.   ""
  3276.   "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
  3277. [(set_attr "conds" "use")
  3278.  (set_attr "length" "8")])
  3279.  
  3280.  
  3281. ;; Jump and linkage insns
  3282.  
  3283. (define_insn "jump"
  3284.   [(set (pc)
  3285.     (label_ref (match_operand 0 "" "")))]
  3286.   ""
  3287.   "*
  3288. {
  3289.   extern int arm_ccfsm_state;
  3290.  
  3291.   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
  3292.   {
  3293.     arm_ccfsm_state += 2;
  3294.     return \"\";
  3295.   }
  3296.   return \"b%?\\t%l0\";
  3297. }")
  3298.  
  3299. (define_expand "call"
  3300.   [(parallel [(call (match_operand 0 "memory_operand" "")
  3301.                 (match_operand 1 "general_operand" ""))
  3302.           (clobber (reg:SI 14))])]
  3303.   ""
  3304.   "")
  3305.  
  3306. (define_insn ""
  3307.   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
  3308.          (match_operand 1 "" "g"))
  3309.    (clobber (reg:SI 14))]
  3310.   ""
  3311.   "*
  3312.   return output_call (operands);
  3313. "
  3314. [(set (attr "conds")
  3315.       (if_then_else (eq_attr "cpu" "arm6")
  3316.             (const_string "clob")
  3317.             (const_string "nocond")))
  3318. ;; length is worst case, normally it is only two
  3319.  (set_attr "length" "12")
  3320.  (set_attr "type" "call")])
  3321.  
  3322. (define_insn ""
  3323.   [(call (mem:SI (match_operand 0 "memory_operand" "m"))
  3324.      (match_operand 1 "general_operand" "g"))
  3325.    (clobber (reg:SI 14))]
  3326.   ""
  3327.   "*
  3328.   return output_call_mem (operands);
  3329. "
  3330. [(set (attr "conds")
  3331.       (if_then_else (eq_attr "cpu" "arm6")
  3332.             (const_string "clob")
  3333.             (const_string "nocond")))
  3334.  (set_attr "length" "12")
  3335.  (set_attr "type" "call")])
  3336.  
  3337. (define_expand "call_value"
  3338.   [(parallel [(set (match_operand 0 "" "=rf")
  3339.                (call (match_operand 1 "memory_operand" "m")
  3340.                  (match_operand 2 "general_operand" "g")))
  3341.           (clobber (reg:SI 14))])]
  3342.   ""
  3343.   "")
  3344.  
  3345. (define_insn ""
  3346.   [(set (match_operand 0 "" "=rf")
  3347.         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
  3348.           (match_operand 2 "general_operand" "g")))
  3349.    (clobber (reg:SI 14))]
  3350.   ""
  3351.   "*
  3352.   return output_call (&operands[1]);
  3353. "
  3354. [(set (attr "conds")
  3355.       (if_then_else (eq_attr "cpu" "arm6")
  3356.             (const_string "clob")
  3357.             (const_string "nocond")))
  3358.  (set_attr "length" "12")
  3359.  (set_attr "type" "call")])
  3360.  
  3361. (define_insn ""
  3362.   [(set (match_operand 0 "" "=rf")
  3363.     (call (mem:SI (match_operand 1 "memory_operand" "m"))
  3364.     (match_operand 2 "general_operand" "g")))
  3365.    (clobber (reg:SI 14))]
  3366.   "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
  3367.   "*
  3368.   return output_call_mem (&operands[1]);
  3369. "
  3370. [(set (attr "conds")
  3371.       (if_then_else (eq_attr "cpu" "arm6")
  3372.             (const_string "clob")
  3373.             (const_string "nocond")))
  3374.  (set_attr "length" "12")
  3375.  (set_attr "type" "call")])
  3376.  
  3377. ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
  3378. ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
  3379.  
  3380. (define_insn ""
  3381.   [(call (mem:SI (match_operand:SI 0 "" "i"))
  3382.      (match_operand:SI 1 "general_operand" "g"))
  3383.    (clobber (reg:SI 14))]
  3384.   "GET_CODE (operands[0]) == SYMBOL_REF"
  3385.   "bl%?\\t%a0"
  3386. [(set (attr "conds")
  3387.       (if_then_else (eq_attr "cpu" "arm6")
  3388.             (const_string "clob")
  3389.             (const_string "nocond")))
  3390.  (set_attr "type" "call")])
  3391.  
  3392. (define_insn ""
  3393.   [(set (match_operand 0 "s_register_operand" "=rf")
  3394.     (call (mem:SI (match_operand:SI 1 "" "i"))
  3395.     (match_operand:SI 2 "general_operand" "g")))
  3396.    (clobber (reg:SI 14))]
  3397.   "GET_CODE(operands[1]) == SYMBOL_REF"
  3398.   "bl%?\\t%a1"
  3399. [(set (attr "conds")
  3400.       (if_then_else (eq_attr "cpu" "arm6")
  3401.             (const_string "clob")
  3402.             (const_string "nocond")))
  3403.  (set_attr "type" "call")])
  3404.  
  3405. ;; Often the return insn will be the same as loading from memory, so set attr
  3406. (define_insn "return"
  3407.   [(return)]
  3408.   "USE_RETURN_INSN"
  3409.   "*
  3410. {
  3411.   extern int arm_ccfsm_state;
  3412.  
  3413.   if (arm_ccfsm_state == 2)
  3414.   {
  3415.     arm_ccfsm_state += 2;
  3416.     return \"\";
  3417.   }
  3418.   return output_return_instruction (NULL, TRUE);
  3419. }"
  3420. [(set_attr "type" "load")])
  3421.  
  3422. (define_insn ""
  3423.   [(set (pc)
  3424.         (if_then_else (match_operator 0 "comparison_operator"
  3425.                [(reg 24) (const_int 0)])
  3426.                       (return)
  3427.                       (pc)))]
  3428.   "USE_RETURN_INSN"
  3429.   "*
  3430. {
  3431.   extern int arm_ccfsm_state;
  3432.  
  3433.   if (arm_ccfsm_state == 2)
  3434.   {
  3435.     arm_ccfsm_state += 2;
  3436.     return \"\";
  3437.   }
  3438.   return output_return_instruction (operands[0], TRUE);
  3439. }"
  3440. [(set_attr "conds" "use")
  3441.  (set_attr "type" "load")])
  3442.  
  3443. (define_insn ""
  3444.   [(set (pc)
  3445.         (if_then_else (match_operator 0 "comparison_operator"
  3446.                [(reg 24) (const_int 0)])
  3447.                       (pc)
  3448.               (return)))]
  3449.   "USE_RETURN_INSN"
  3450.   "*
  3451. {
  3452.   extern int arm_ccfsm_state;
  3453.  
  3454.   if (arm_ccfsm_state == 2)
  3455.   {
  3456.     arm_ccfsm_state += 2;
  3457.     return \"\";
  3458.   }
  3459.   return output_return_instruction 
  3460.     (gen_rtx (reverse_condition (GET_CODE (operands[0])),
  3461.           GET_MODE (operands[0]), XEXP (operands[0], 0),
  3462.           XEXP (operands[0], 1)),
  3463.      TRUE);
  3464. }"
  3465. [(set_attr "conds" "use")
  3466.  (set_attr "type" "load")])
  3467.  
  3468. ;; Call subroutine returning any type.
  3469.  
  3470. (define_expand "untyped_call"
  3471.   [(parallel [(call (match_operand 0 "" "")
  3472.             (const_int 0))
  3473.           (match_operand 1 "" "")
  3474.           (match_operand 2 "" "")])]
  3475.   ""
  3476.   "
  3477. {
  3478.   int i;
  3479.  
  3480.   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
  3481.  
  3482.   for (i = 0; i < XVECLEN (operands[2], 0); i++)
  3483.     {
  3484.       rtx set = XVECEXP (operands[2], 0, i);
  3485.       emit_move_insn (SET_DEST (set), SET_SRC (set));
  3486.     }
  3487.  
  3488.   /* The optimizer does not know that the call sets the function value
  3489.      registers we stored in the result block.  We avoid problems by
  3490.      claiming that all hard registers are used and clobbered at this
  3491.      point.  */
  3492.   emit_insn (gen_blockage ());
  3493.  
  3494.   DONE;
  3495. }")
  3496.  
  3497. ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
  3498. ;; all of memory.  This blocks insns from being moved across this point.
  3499.  
  3500. (define_insn "blockage"
  3501.   [(unspec_volatile [(const_int 0)] 0)]
  3502.   ""
  3503.   ""
  3504. [(set_attr "length" "0")
  3505.  (set_attr "type" "block")])
  3506.  
  3507. (define_insn "tablejump"
  3508.   [(set (pc)
  3509.     (match_operand:SI 0 "s_register_operand" "r"))
  3510.    (use (label_ref (match_operand 1 "" "")))]
  3511.   ""
  3512.   "mov%?\\t%|pc, %0\\t%@ table jump, label %l1")
  3513.  
  3514. (define_insn ""
  3515.   [(set (pc)
  3516.     (match_operand:SI 0 "memory_operand" "m"))
  3517.    (use (label_ref (match_operand 1 "" "")))]
  3518.   ""
  3519.   "ldr%?\\t%|pc, %0\\t%@ table jump, label %l1"
  3520. [(set_attr "type" "load")])
  3521.  
  3522. (define_insn "indirect_jump"
  3523.   [(set (pc)
  3524.     (match_operand:SI 0 "s_register_operand" "r"))]
  3525.   ""
  3526.   "mov%?\\t%|pc, %0\\t%@ indirect jump")
  3527.  
  3528. (define_insn ""
  3529.   [(set (pc)
  3530.     (match_operand:SI 0 "memory_operand" "m"))]
  3531.   ""
  3532.   "ldr%?\\t%|pc, %0\\t%@ indirect jump"
  3533. [(set_attr "type" "load")])
  3534.  
  3535. ;; Misc insns
  3536.  
  3537. (define_insn "nop"
  3538.   [(const_int 0)]
  3539.   ""
  3540.   "mov%?\\tr0, r0\\t%@ nop")
  3541.  
  3542. ;; Patterns to allow combination of arithmetic, cond code and shifts
  3543.  
  3544. (define_insn ""
  3545.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3546.         (match_operator:SI 1 "shiftable_operator"
  3547.           [(match_operator:SI 3 "shift_operator"
  3548.              [(match_operand:SI 4 "s_register_operand" "r")
  3549.               (match_operand:SI 5 "reg_or_int_operand" "rI")])
  3550.            (match_operand:SI 2 "s_register_operand" "r")]))]
  3551.   ""
  3552.   "%i1%?\\t%0, %2, %4%S3")
  3553.  
  3554. (define_insn ""
  3555.   [(set (reg:CC_NOOV 24)
  3556.         (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
  3557.                   [(match_operator:SI 3 "shift_operator"
  3558.                     [(match_operand:SI 4 "s_register_operand" "r")
  3559.                      (match_operand:SI 5 "reg_or_int_operand" "rI")])
  3560.                    (match_operand:SI 2 "s_register_operand" "r")])
  3561.              (const_int 0)))
  3562.    (set (match_operand:SI 0 "s_register_operand" "=r")
  3563.     (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
  3564.              (match_dup 2)]))]
  3565.   ""
  3566.   "%i1%?s\\t%0, %2, %4%S3"
  3567. [(set_attr "conds" "set")])
  3568.  
  3569. (define_insn ""
  3570.   [(set (reg:CC_NOOV 24)
  3571.         (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
  3572.                   [(match_operator:SI 3 "shift_operator"
  3573.                     [(match_operand:SI 4 "s_register_operand" "r")
  3574.                      (match_operand:SI 5 "reg_or_int_operand" "rI")])
  3575.                    (match_operand:SI 2 "s_register_operand" "r")])
  3576.              (const_int 0)))
  3577.    (clobber (match_scratch:SI 0 "=r"))]
  3578.   ""
  3579.   "%i1%?s\\t%0, %2, %4%S3"
  3580. [(set_attr "conds" "set")])
  3581.  
  3582. (define_insn ""
  3583.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3584.     (minus:SI (match_operand:SI 1 "s_register_operand" "r")
  3585.           (match_operator:SI 2 "shift_operator"
  3586.            [(match_operand:SI 3 "s_register_operand" "r")
  3587.             (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
  3588.   ""
  3589.   "sub%?\\t%0, %1, %3%S2")
  3590.  
  3591. (define_insn ""
  3592.   [(set (reg:CC_NOOV 24)
  3593.     (compare:CC_NOOV
  3594.      (minus:SI (match_operand:SI 1 "s_register_operand" "r")
  3595.            (match_operator:SI 2 "shift_operator"
  3596.             [(match_operand:SI 3 "s_register_operand" "r")
  3597.              (match_operand:SI 4 "reg_or_int_operand" "rM")]))
  3598.      (const_int 0)))
  3599.    (set (match_operand:SI 0 "s_register_operand" "=r")
  3600.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  3601.                          (match_dup 4)])))]
  3602.   ""
  3603.   "sub%?s\\t%0, %1, %3%S2"
  3604. [(set_attr "conds" "set")])
  3605.  
  3606. (define_insn ""
  3607.   [(set (reg:CC_NOOV 24)
  3608.     (compare:CC_NOOV
  3609.      (minus:SI (match_operand:SI 1 "s_register_operand" "r")
  3610.            (match_operator:SI 2 "shift_operator"
  3611.             [(match_operand:SI 3 "s_register_operand" "r")
  3612.              (match_operand:SI 4 "reg_or_int_operand" "rM")]))
  3613.      (const_int 0)))
  3614.    (clobber (match_scratch:SI 0 "=r"))]
  3615.   ""
  3616.   "sub%?s\\t%0, %1, %3%S2"
  3617. [(set_attr "conds" "set")])
  3618.  
  3619. ;; These variants of the above insns can occur if the first operand is the
  3620. ;; frame pointer and we eliminate that.  This is a kludge, but there doesn't
  3621. ;; seem to be a way around it.  Most of the predicates have to be null
  3622. ;; because the format can be generated part way through reload, so
  3623. ;; if we don't match it as soon as it becomes available, reload doesn't know
  3624. ;; how to reload pseudos that haven't got hard registers; the constraints will
  3625. ;; sort everything out.
  3626.  
  3627. (define_insn ""
  3628.   [(set (match_operand:SI 0 "" "=&r")
  3629.     (plus:SI (plus:SI (match_operator:SI 5 "shift_operator"
  3630.                [(match_operand:SI 3 "" "r")
  3631.                 (match_operand:SI 4 "" "rM")])
  3632.               (match_operand:SI 2 "" "r"))
  3633.          (match_operand:SI 1 "const_int_operand" "n")))]
  3634.   "reload_in_progress"
  3635.   "*
  3636.   output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands);
  3637.   operands[2] = operands[1];
  3638.   operands[1] = operands[0];
  3639.   return output_add_immediate (operands);
  3640. "
  3641. ; we have no idea how long the add_immediate is, it could be up to 4.
  3642. [(set_attr "length" "20")])
  3643.  
  3644. (define_insn ""
  3645.   [(set (reg:CC_NOOV 24)
  3646.     (compare:CC_NOOV (plus:SI
  3647.               (plus:SI 
  3648.                (match_operator:SI 5 "shift_operator"
  3649.                 [(match_operand:SI 3 "" "r")
  3650.                  (match_operand:SI 4 "" "rM")])
  3651.                (match_operand:SI 1 "" "r"))
  3652.               (match_operand:SI 2 "const_int_operand" "n"))
  3653.              (const_int 0)))
  3654.    (set (match_operand:SI 0 "" "=&r")
  3655.     (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)])
  3656.               (match_dup 1))
  3657.          (match_dup 2)))]
  3658.   "reload_in_progress"
  3659.   "*
  3660.   output_add_immediate (operands);
  3661.   return \"add%?s\\t%0, %0, %3%S5\";
  3662. "
  3663. [(set_attr "conds" "set")
  3664.  (set_attr "length" "20")])
  3665.  
  3666. (define_insn ""
  3667.   [(set (reg:CC_NOOV 24)
  3668.     (compare:CC_NOOV (plus:SI
  3669.               (plus:SI 
  3670.                (match_operator:SI 5 "shift_operator"
  3671.                 [(match_operand:SI 3 "" "r")
  3672.                  (match_operand:SI 4 "" "rM")])
  3673.                (match_operand:SI 1 "" "r"))
  3674.               (match_operand:SI 2 "const_int_operand" "n"))
  3675.              (const_int 0)))
  3676.    (clobber (match_scratch:SI 0 "=&r"))]
  3677.   "reload_in_progress"
  3678.   "*
  3679.   output_add_immediate (operands);
  3680.   return \"add%?s\\t%0, %0, %3%S5\";
  3681. "
  3682. [(set_attr "conds" "set")
  3683.  (set_attr "length" "20")])
  3684.  
  3685. ;; These are similar, but are needed when the mla pattern contains the
  3686. ;; eliminated register as operand 3.
  3687.  
  3688. (define_insn ""
  3689.   [(set (match_operand:SI 0 "" "=&r,&r")
  3690.     (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r")
  3691.                    (match_operand:SI 2 "" "r,r"))
  3692.               (match_operand:SI 3 "" "r,r"))
  3693.          (match_operand:SI 4 "const_int_operand" "n,n")))]
  3694.   "reload_in_progress"
  3695.   "*
  3696.   output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands);
  3697.   operands[2] = operands[4];
  3698.   operands[1] = operands[0];
  3699.   return output_add_immediate (operands);
  3700. "
  3701. [(set_attr "length" "20")])
  3702.  
  3703. (define_insn ""
  3704.   [(set (reg:CC_NOOV 24)
  3705.     (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
  3706.                         (match_operand:SI 3 "" "r")
  3707.                         (match_operand:SI 4 "" "r"))
  3708.                        (match_operand:SI 1 "" "r"))
  3709.                   (match_operand:SI 2 "const_int_operand" "n"))
  3710.              (const_int 0)))
  3711.    (set (match_operand:SI 0 "" "=&r")
  3712.     (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1))
  3713.          (match_dup 2)))]
  3714.   "reload_in_progress"
  3715.   "*
  3716.   output_add_immediate (operands);
  3717.   output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands);
  3718.   return \"\";
  3719. "
  3720. [(set_attr "length" "20")
  3721.  (set_attr "conds" "set")])
  3722.  
  3723. (define_insn ""
  3724.   [(set (reg:CC_NOOV 24)
  3725.     (compare:CC_NOOV (plus:SI (plus:SI (mult:SI
  3726.                         (match_operand:SI 3 "" "r")
  3727.                         (match_operand:SI 4 "" "r"))
  3728.                        (match_operand:SI 1 "" "r"))
  3729.                   (match_operand:SI 2 "const_int_operand" "n"))
  3730.              (const_int 0)))
  3731.    (clobber (match_scratch:SI 0 "=&r"))]
  3732.   "reload_in_progress"
  3733.   "*
  3734.   output_add_immediate (operands);
  3735.   return \"mla%?s\\t%0, %3, %4, %0\";
  3736. "
  3737. [(set_attr "length" "20")
  3738.  (set_attr "conds" "set")])
  3739.  
  3740.  
  3741.  
  3742.  
  3743. (define_insn ""
  3744.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  3745.     (and:SI (match_operator 1 "comparison_operator"
  3746.          [(match_operand 3 "reversible_cc_register" "") (const_int 0)])
  3747.         (match_operand:SI 2 "s_register_operand" "r")))]
  3748.   ""
  3749.   "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
  3750. [(set_attr "conds" "use")
  3751.  (set_attr "length" "8")])
  3752.  
  3753. (define_insn ""
  3754.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  3755.     (ior:SI (match_operator 2 "comparison_operator"
  3756.          [(reg 24) (const_int 0)])
  3757.         (match_operand:SI 1 "s_register_operand" "0,?r")))]
  3758.   ""
  3759.   "@
  3760.    orr%d2\\t%0, %1, #1
  3761.    mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
  3762. [(set_attr "conds" "use")
  3763.  (set_attr "length" "4,8")])
  3764.  
  3765. (define_insn ""
  3766.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  3767.     (match_operator 1 "comparison_operator"
  3768.      [(match_operand:SI 2 "s_register_operand" "r,r")
  3769.       (match_operand:SI 3 "arm_add_operand" "rI,L")]))
  3770.    (clobber (reg 24))]
  3771.   ""
  3772.   "*
  3773.   if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
  3774.     return \"mov\\t%0, %2, lsr #31\";
  3775.  
  3776.   if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
  3777.     return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
  3778.  
  3779.   if (GET_CODE (operands[1]) == NE)
  3780.     {
  3781.       if (which_alternative == 1)
  3782.     return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
  3783.       return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
  3784.     }
  3785.   if (which_alternative == 1)
  3786.     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
  3787.   else
  3788.     output_asm_insn (\"cmp\\t%2, %3\", operands);
  3789.   return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
  3790. "
  3791. [(set_attr "conds" "clob")
  3792.  (set_attr "length" "12")])
  3793.  
  3794. (define_insn ""
  3795.   [(set (match_operand:SI 0 "s_register_operand" "=&r")
  3796.     (ior:SI (match_operator 1 "comparison_operator"
  3797.          [(match_operand:SI 2 "s_register_operand" "r")
  3798.           (match_operand:SI 3 "arm_rhs_operand" "rI")])
  3799.         (match_operator 4 "comparison_operator"
  3800.          [(match_operand:SI 5 "s_register_operand" "r")
  3801.           (match_operand:SI 6 "arm_rhs_operand" "rI")])))
  3802.    (clobber (reg 24))]
  3803.   ""
  3804.   "*
  3805. {
  3806.   int dominant = comparison_dominates_p (GET_CODE (operands[4]),
  3807.                      GET_CODE (operands[1]));
  3808.  
  3809.   output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
  3810.            operands);
  3811.   output_asm_insn (\"mov\\t%0, #0\", operands);
  3812.   if (GET_CODE (operands[1]) == GET_CODE (operands[4])
  3813.       || comparison_dominates_p (GET_CODE (operands[1]),
  3814.                  GET_CODE (operands[4]))
  3815.       || dominant)
  3816.     output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\",
  3817.              operands);
  3818.   else
  3819.     output_asm_insn (\"mov%d1\\t%0, #1\;cmp\\t%5, %6\", operands);
  3820.   return dominant ? \"mov%d1\\t%0, #1\" : \"mov%d4\\t%0, #1\";
  3821. }
  3822. "
  3823. [(set_attr "conds" "clob")
  3824. ; worst case length
  3825.  (set_attr "length" "20")])
  3826.  
  3827. (define_split
  3828.   [(set (pc)
  3829.     (if_then_else
  3830.      (match_operator 5 "equality_operator"
  3831.       [(ior:SI (match_operator 6 "comparison_operator"
  3832.             [(match_operand:SI 0 "s_register_operand" "")
  3833.              (match_operand:SI 1 "arm_add_operand" "")])
  3834.            (match_operator 7 "comparison_operator"
  3835.             [(match_operand:SI 2 "s_register_operand" "")
  3836.              (match_operand:SI 3 "arm_add_operand" "")]))
  3837.       (const_int 0)])
  3838.      (label_ref (match_operand 4 "" ""))
  3839.      (pc)))
  3840.    (clobber (reg 24))]
  3841.   "(GET_CODE (operands[6]) == GET_CODE (operands[7])
  3842.     || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7]))
  3843.     || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))"
  3844.   [(set (reg:CC 24)
  3845.     (compare:CC (ior:CC (match_op_dup 6
  3846.                  [(match_dup 0) (match_dup 1)])
  3847.                 (match_op_dup 7
  3848.                  [(match_dup 2) (match_dup 3)]))
  3849.             (const_int 0)))
  3850.    (set (pc)
  3851.         (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)])
  3852.               (label_ref (match_dup 4))
  3853.               (pc)))]
  3854.   "
  3855. {
  3856.   enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]),
  3857.                            GET_CODE (operands[7]))
  3858.                ? GET_CODE (operands[7]) : GET_CODE (operands[6]);
  3859.  
  3860.   if (GET_CODE (operands[5]) == NE)
  3861.     operands[5] = gen_rtx (code, CCmode,
  3862.                XEXP (operands[5], 0), XEXP (operands[5], 1));
  3863.   else
  3864.     operands[5] = gen_rtx (reverse_condition (code), CCmode,
  3865.                XEXP (operands[5], 0), XEXP (operands[5], 1));
  3866. }
  3867. ")
  3868.  
  3869. ;; Don't match these patterns if we can use a conditional compare, since they
  3870. ;; tell the final prescan branch elimator code that full branch inlining
  3871. ;; can't be done.
  3872.  
  3873. (define_insn ""
  3874.   [(set (pc)
  3875.     (if_then_else
  3876.      (ne (ior:SI (match_operator 5 "comparison_operator"
  3877.               [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
  3878.                (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
  3879.              (match_operator 6 "comparison_operator"
  3880.               [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
  3881.                (match_operand:SI 3 "arm_rhs_operand" "rI,rI,L,L")]))
  3882.          (const_int 0))
  3883.      (label_ref (match_operand 4 "" ""))
  3884.      (pc)))
  3885.    (clobber (reg 24))]
  3886.   "!(GET_CODE (operands[5]) == GET_CODE (operands[6])
  3887.      || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6]))
  3888.      || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))"
  3889.   "*
  3890. {
  3891.   extern int arm_ccfsm_state;
  3892.  
  3893.   if (which_alternative & 1)
  3894.     output_asm_insn (\"cmn\\t%0, #%n1\;b%d5\\t%l4\", operands);
  3895.   else
  3896.     output_asm_insn (\"cmp\\t%0, %1\;b%d5\\t%l4\", operands);
  3897.  
  3898.   if (which_alternative >= 2)
  3899.     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
  3900.   else
  3901.     output_asm_insn (\"cmp\\t%2, %3\", operands);
  3902.  
  3903.   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
  3904.   {
  3905.     arm_ccfsm_state += 2;
  3906.     return \"\";
  3907.   }
  3908.   return \"b%d6\\t%l4\";
  3909. }"
  3910. [(set_attr "conds" "jump_clob")
  3911.  (set_attr "length" "16")])
  3912.  
  3913. (define_insn ""
  3914.   [(set (reg:CC 24)
  3915.     (compare:CC
  3916.      (ior:CC (match_operator 4 "comparison_operator"
  3917.           [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
  3918.            (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
  3919.          (match_operator 5 "comparison_operator"
  3920.           [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
  3921.            (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
  3922.      (const_int 0)))]
  3923.   "(GET_CODE (operands[4]) == GET_CODE (operands[5])
  3924.     || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5]))
  3925.     || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))"
  3926.   "*
  3927.   if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))
  3928.     {
  3929.       if (which_alternative >= 2)
  3930.     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
  3931.       else
  3932.     output_asm_insn (\"cmp\\t%2, %3\", operands);
  3933.  
  3934.       if (which_alternative & 1)
  3935.     return \"cmn%D5\\t%0, #%n1\";
  3936.       return \"cmp%D5\\t%0, %1\";
  3937.     }
  3938.  
  3939.   if (which_alternative & 1)
  3940.     output_asm_insn (\"cmn\\t%0, #%n1\", operands);
  3941.   else
  3942.     output_asm_insn (\"cmp\\t%0, %1\", operands);
  3943.  
  3944.   if (which_alternative >= 2)
  3945.     return \"cmn%D4\\t%2, #%n3\";
  3946.   return \"cmp%D4\\t%2, %3\";
  3947. "
  3948. [(set_attr "conds" "set")
  3949.  (set_attr "length" "8")])
  3950.  
  3951. (define_insn ""
  3952.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  3953.     (if_then_else (match_operator 3 "equality_operator"
  3954.                [(match_operator 4 "comparison_operator"
  3955.              [(reg 24) (const_int 0)])
  3956.             (const_int 0)])
  3957.               (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
  3958.               (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
  3959.   ""
  3960.   "*
  3961.   if (GET_CODE (operands[3]) == NE)
  3962.     {
  3963.       if (which_alternative != 1)
  3964.     output_asm_insn (\"mov%D4\\t%0, %2\", operands);
  3965.       if (which_alternative != 0)
  3966.     output_asm_insn (\"mov%d4\\t%0, %1\", operands);
  3967.       return \"\";
  3968.     }
  3969.   if (which_alternative != 0)
  3970.     output_asm_insn (\"mov%D4\\t%0, %1\", operands);
  3971.   if (which_alternative != 1)
  3972.     output_asm_insn (\"mov%d4\\t%0, %2\", operands);
  3973.   return \"\";
  3974. "
  3975. [(set_attr "conds" "use")
  3976.  (set_attr "length" "4,4,8")])
  3977.  
  3978. (define_insn ""
  3979.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  3980.         (match_operator:SI 5 "shiftable_operator" 
  3981.      [(match_operator:SI 4 "comparison_operator"
  3982.            [(match_operand:SI 2 "s_register_operand" "r,r")
  3983.         (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
  3984.           (match_operand:SI 1 "s_register_operand" "0,?r")]))
  3985.    (clobber (reg 24))]
  3986.   ""
  3987.   "*
  3988.   if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
  3989.     return \"%i5\\t%0, %1, %2, lsr #31\";
  3990.  
  3991.   output_asm_insn (\"cmp\\t%2, %3\", operands);
  3992.   if (GET_CODE (operands[5]) == AND)
  3993.     output_asm_insn (\"mov%D4\\t%0, #0\", operands);
  3994.   else if (which_alternative != 0)
  3995.     output_asm_insn (\"mov%D4\\t%0, %1\", operands);
  3996.   return \"%i5%d4\\t%0, %1, #1\";
  3997. "
  3998. [(set_attr "conds" "clob")
  3999.  (set_attr "length" "12")])
  4000.  
  4001. (define_insn ""
  4002.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4003.         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
  4004.           (match_operator:SI 4 "comparison_operator"
  4005.                    [(match_operand:SI 2 "s_register_operand" "r,r")
  4006.             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
  4007.    (clobber (reg 24))]
  4008.   ""
  4009.   "*
  4010.   output_asm_insn (\"cmp\\t%2, %3\", operands);
  4011.   if (which_alternative != 0)
  4012.     output_asm_insn (\"mov%D4\\t%0, %1\", operands);
  4013.   return \"sub%d4\\t%0, %1, #1\";
  4014. "
  4015. [(set_attr "conds" "clob")
  4016.  (set_attr "length" "8,12")])
  4017.  
  4018. (define_insn ""
  4019.   [(set (match_operand:SI 0 "s_register_operand" "=&r")
  4020.     (and:SI (match_operator 1 "comparison_operator"
  4021.          [(match_operand:SI 2 "s_register_operand" "r")
  4022.           (match_operand:SI 3 "arm_rhs_operand" "rI")])
  4023.         (match_operator 4 "comparison_operator"
  4024.          [(match_operand:SI 5 "s_register_operand" "r")
  4025.           (match_operand:SI 6 "arm_rhs_operand" "rI")])))
  4026.    (clobber (reg 24))]
  4027.   ""
  4028.   "*
  4029. {
  4030.   int dominant =
  4031.     comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
  4032.                 reverse_condition (GET_CODE (operands[4])))
  4033.     ? 1 
  4034.     : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
  4035.                   reverse_condition (GET_CODE (operands[1])))
  4036.     ? 2 : 0;
  4037.   output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\",
  4038.                operands);
  4039.   output_asm_insn (\"mov\\t%0, #1\", operands);
  4040.   if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant)
  4041.     {
  4042.       output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\"
  4043.                : \"cmp%d1\\t%5, %6\", operands);
  4044.     }
  4045.   else
  4046.     {
  4047.       output_asm_insn (\"mov%D1\\t%0, #0\", operands);
  4048.       output_asm_insn (\"cmp\\t%5, %6\", operands);
  4049.     }
  4050.   return dominant == 2 ? \"mov%D1\\t%0, #0\" : \"mov%D4\\t%0, #0\";
  4051. }
  4052. "
  4053. [(set_attr "conds" "clob")
  4054.  (set_attr "length" "20")])
  4055.  
  4056. (define_split
  4057.   [(set (pc)
  4058.     (if_then_else (match_operator 1 "equality_operator"
  4059.                [(and:SI (match_operator 2 "comparison_operator"
  4060.                  [(match_operand:SI 3 "s_register_operand" "")
  4061.                   (match_operand:SI 4 "arm_add_operand" "")])
  4062.                 (match_operator 0 "comparison_operator"
  4063.                  [(match_operand:SI 5 "s_register_operand" "")
  4064.                   (match_operand:SI 6 "arm_add_operand" "")]))
  4065.             (const_int 0)])
  4066.               (label_ref (match_operand 7 "" ""))
  4067.               (pc)))
  4068.    (clobber (reg 24))]
  4069.   "(GET_CODE (operands[2]) == GET_CODE (operands[0])
  4070.     || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
  4071.                    reverse_condition (GET_CODE (operands[0])))
  4072.     || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])),
  4073.                    reverse_condition (GET_CODE (operands[2]))))"
  4074.   [(set (reg:CC 24)
  4075.     (compare:CC (ior:CC (match_op_dup 2
  4076.                  [(match_dup 3) (match_dup 4)])
  4077.                 (match_op_dup 0
  4078.                  [(match_dup 5) (match_dup 6)]))
  4079.             (const_int 0)))
  4080.    (set (pc)
  4081.         (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)])
  4082.               (label_ref (match_dup 7))
  4083.               (pc)))]
  4084.   "
  4085. {
  4086.   /* Use DeMorgans law to convert this into an IOR of the inverse conditions 
  4087.      This is safe since we only do it for integer comparisons. */
  4088.   enum rtx_code code = 
  4089.     comparison_dominates_p (reverse_condition (GET_CODE (operands[2])),
  4090.                 reverse_condition (GET_CODE (operands[0])))
  4091.     ? GET_CODE (operands[0]) : GET_CODE (operands[2]);
  4092.  
  4093.   operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])),
  4094.              GET_MODE (operands[2]), operands[3], operands[4]);
  4095.   operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])),
  4096.              GET_MODE (operands[0]), operands[5], operands[6]);
  4097.   if (GET_CODE (operands[1]) == NE)
  4098.     operands[1] = gen_rtx (code, CCmode,
  4099.                XEXP (operands[1], 0), XEXP (operands[1], 1));
  4100.   else
  4101.     operands[1] = gen_rtx (reverse_condition (code), CCmode,
  4102.                XEXP (operands[1], 0), XEXP (operands[1], 1));
  4103. }
  4104. ")
  4105.  
  4106. ;; Don't match these patterns if we can use a conditional compare, since they
  4107. ;; tell the final prescan branch elimator code that full branch inlining
  4108. ;; can't be done.
  4109.  
  4110. (define_insn ""
  4111.   [(set (pc)
  4112.     (if_then_else
  4113.      (eq (and:SI (match_operator 1 "comparison_operator"
  4114.               [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
  4115.                (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")])
  4116.              (match_operator 4 "comparison_operator"
  4117.               [(match_operand:SI 5 "s_register_operand" "r,r,r,r")
  4118.                (match_operand:SI 6 "arm_rhs_operand" "rI,rI,L,L")]))
  4119.          (const_int 0))
  4120.      (label_ref (match_operand 0 "" ""))
  4121.      (pc)))
  4122.    (clobber (reg 24))]
  4123.   "!(GET_CODE (operands[1]) == GET_CODE (operands[4])
  4124.      || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])),
  4125.                     reverse_condition (GET_CODE (operands[4])))
  4126.      || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])),
  4127.                     reverse_condition (GET_CODE (operands[1]))))"
  4128.   "*
  4129. {
  4130.   extern int arm_ccfsm_state;
  4131.  
  4132.   if (which_alternative & 1)
  4133.     output_asm_insn (\"cmn\\t%2, #%n3\;b%D1\\t%l0\", operands);
  4134.   else
  4135.     output_asm_insn (\"cmp\\t%2, %3\;b%D1\\t%l0\", operands);
  4136.  
  4137.   if (which_alternative >= 2)
  4138.     output_asm_insn (\"cmn\\t%5, #%n6\", operands);
  4139.   else
  4140.     output_asm_insn (\"cmp\\t%5, %6\", operands);
  4141.  
  4142.   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
  4143.   {
  4144.     arm_ccfsm_state += 2;
  4145.     return \"\";
  4146.   }
  4147.   return \"b%D4\\t%l0\";
  4148. }"
  4149. [(set_attr "conds" "jump_clob")
  4150.  (set_attr "length" "16")])
  4151.  
  4152. (define_insn ""
  4153.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  4154.     (neg:SI (match_operator 3 "comparison_operator"
  4155.          [(match_operand:SI 1 "s_register_operand" "r")
  4156.           (match_operand:SI 2 "arm_rhs_operand" "rI")])))
  4157.    (clobber (reg 24))]
  4158.   ""
  4159.   "*
  4160.   if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
  4161.     return \"mov\\t%0, %1, asr #31\";
  4162.  
  4163.   if (GET_CODE (operands[3]) == NE)
  4164.     return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
  4165.  
  4166.   if (GET_CODE (operands[3]) == GT)
  4167.     return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
  4168.  
  4169.   output_asm_insn (\"cmp\\t%1, %2\", operands);
  4170.   output_asm_insn (\"mov%D3\\t%0, #0\", operands);
  4171.   return \"mvn%d3\\t%0, #0\";
  4172. "
  4173. [(set_attr "conds" "clob")
  4174.  (set_attr "length" "12")])
  4175.  
  4176. (define_insn "movcond"
  4177.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
  4178.     (if_then_else:SI
  4179.      (match_operator 5 "comparison_operator"
  4180.       [(match_operand:SI 3 "s_register_operand" "r,r,r")
  4181.        (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
  4182.      (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
  4183.      (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
  4184.    (clobber (reg 24))]
  4185.   ""
  4186.   "*
  4187.   if (GET_CODE (operands[5]) == LT
  4188.       && (operands[4] == const0_rtx))
  4189.     {
  4190.       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
  4191.     {
  4192.       if (operands[2] == const0_rtx)
  4193.         return \"and\\t%0, %1, %3, asr #31\";
  4194.       return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
  4195.     }
  4196.       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
  4197.     {
  4198.       if (operands[1] == const0_rtx)
  4199.         return \"bic\\t%0, %2, %3, asr #31\";
  4200.       return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
  4201.     }
  4202.       /* The only case that falls through to here is when both ops 1 & 2
  4203.      are constants */
  4204.     }
  4205.  
  4206.   if (GET_CODE (operands[5]) == GE
  4207.       && (operands[4] == const0_rtx))
  4208.     {
  4209.       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
  4210.     {
  4211.       if (operands[2] == const0_rtx)
  4212.         return \"bic\\t%0, %1, %3, asr #31\";
  4213.       return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
  4214.     }
  4215.       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
  4216.     {
  4217.       if (operands[1] == const0_rtx)
  4218.         return \"and\\t%0, %2, %3, asr #31\";
  4219.       return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
  4220.     }
  4221.       /* The only case that falls through to here is when both ops 1 & 2
  4222.      are constants */
  4223.     }
  4224.   if (GET_CODE (operands[4]) == CONST_INT
  4225.       && !const_ok_for_arm (INTVAL (operands[4])))
  4226.     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
  4227.   else
  4228.     output_asm_insn (\"cmp\\t%3, %4\", operands);
  4229.   if (which_alternative != 0)
  4230.     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
  4231.   if (which_alternative != 1)
  4232.     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
  4233.   return \"\";
  4234. "
  4235. [(set_attr "conds" "clob")
  4236.  (set_attr "length" "8,8,12")])
  4237.  
  4238. (define_insn ""
  4239.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4240.     (if_then_else:SI (match_operator 9 "comparison_operator"
  4241.               [(match_operand:SI 5 "s_register_operand" "r,r")
  4242.                (match_operand:SI 6 "arm_add_operand" "rI,L")])
  4243.              (match_operator:SI 8 "shiftable_operator"
  4244.               [(match_operand:SI 1 "s_register_operand" "r,r")
  4245.                (match_operand:SI 2 "arm_rhs_operand" "rI,rI")])
  4246.              (match_operator:SI 7 "shiftable_operator"
  4247.               [(match_operand:SI 3 "s_register_operand" "r,r")
  4248.                (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
  4249.    (clobber (reg 24))]
  4250.   ""
  4251.   "@
  4252.    cmp\\t%5, %6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4
  4253.    cmn\\t%5, #%n6\;%I8%d9\\t%0, %1, %2\;%I7%D9\\t%0, %3, %4"
  4254. [(set_attr "conds" "clob")
  4255.  (set_attr "length" "12")])
  4256.  
  4257. (define_insn ""
  4258.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4259.     (if_then_else:SI (match_operator 6 "comparison_operator"
  4260.               [(match_operand:SI 2 "s_register_operand" "r,r")
  4261.                (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
  4262.              (match_operator:SI 7 "shiftable_operator"
  4263.               [(match_operand:SI 4 "s_register_operand" "r,r")
  4264.                (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
  4265.              (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
  4266.    (clobber (reg 24))]
  4267.   ""
  4268.   "*
  4269.   /* If we have an operation where (op x 0) is the identity operation and
  4270.      the condtional operator is LT or GE and we are comparing against zero and
  4271.      everything is in registers then we can do this in two instructions */
  4272.   if (operands[3] == const0_rtx
  4273.       && GET_CODE (operands[7]) != AND
  4274.       && GET_CODE (operands[5]) == REG
  4275.       && GET_CODE (operands[1]) == REG 
  4276.       && REGNO (operands[1]) == REGNO (operands[4])
  4277.       && REGNO (operands[4]) != REGNO (operands[0]))
  4278.     {
  4279.       if (GET_CODE (operands[6]) == LT)
  4280.     return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
  4281.       else if (GET_CODE (operands[6]) == GE)
  4282.     return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
  4283.     }
  4284.   if (GET_CODE (operands[3]) == CONST_INT
  4285.       && !const_ok_for_arm (INTVAL (operands[3])))
  4286.     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
  4287.   else
  4288.     output_asm_insn (\"cmp\\t%2, %3\", operands);
  4289.   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
  4290.   if (which_alternative != 0)
  4291.     {
  4292.       if (GET_CODE (operands[1]) == MEM)
  4293.     return \"ldr%D6\\t%0, %1\";
  4294.       else
  4295.     return \"mov%D6\\t%0, %1\";
  4296.     }
  4297.   return \"\";
  4298. "
  4299. [(set_attr "conds" "clob")
  4300.  (set_attr "length" "8,12")])
  4301.  
  4302. (define_insn ""
  4303.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4304.     (if_then_else:SI (match_operator 6 "comparison_operator"
  4305.               [(match_operand:SI 4 "s_register_operand" "r,r")
  4306.                (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
  4307.              (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
  4308.              (match_operator:SI 7 "shiftable_operator"
  4309.               [(match_operand:SI 2 "s_register_operand" "r,r")
  4310.                (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
  4311.    (clobber (reg 24))]
  4312.   ""
  4313.   "*
  4314.   /* If we have an operation where (op x 0) is the identity operation and
  4315.      the condtional operator is LT or GE and we are comparing against zero and
  4316.      everything is in registers then we can do this in two instructions */
  4317.   if (operands[5] == const0_rtx
  4318.       && GET_CODE (operands[7]) != AND
  4319.       && GET_CODE (operands[3]) == REG
  4320.       && GET_CODE (operands[1]) == REG 
  4321.       && REGNO (operands[1]) == REGNO (operands[2])
  4322.       && REGNO (operands[2]) != REGNO (operands[0]))
  4323.     {
  4324.       if (GET_CODE (operands[6]) == GE)
  4325.     return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
  4326.       else if (GET_CODE (operands[6]) == LT)
  4327.     return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
  4328.     }
  4329.  
  4330.   if (GET_CODE (operands[5]) == CONST_INT
  4331.       && !const_ok_for_arm (INTVAL (operands[5])))
  4332.     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
  4333.   else
  4334.     output_asm_insn (\"cmp\\t%4, %5\", operands);
  4335.  
  4336.   if (which_alternative != 0)
  4337.     {
  4338.       if (GET_CODE (operands[1]) == MEM)
  4339.     output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
  4340.       else
  4341.     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
  4342.     }
  4343.   return \"%I7%D6\\t%0, %2, %3\";
  4344. "
  4345. [(set_attr "conds" "clob")
  4346.  (set_attr "length" "8,12")])
  4347.  
  4348. (define_insn ""
  4349.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4350.     (if_then_else:SI (match_operator 6 "comparison_operator"
  4351.               [(match_operand:SI 4 "s_register_operand" "r,r")
  4352.                (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
  4353.              (plus:SI
  4354.               (match_operand:SI 2 "s_register_operand" "r,r")
  4355.               (match_operand:SI 3 "arm_add_operand" "rL,rL"))
  4356.              (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")))
  4357.    (clobber (reg 24))]
  4358.   ""
  4359.   "*
  4360. {
  4361.   if (GET_CODE (operands[5]) == CONST_INT
  4362.       && !const_ok_for_arm (INTVAL (operands[5])))
  4363.     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
  4364.   else
  4365.     output_asm_insn (\"cmp\\t%4, %5\", operands);
  4366.   if (GET_CODE (operands[3]) == CONST_INT
  4367.       && !const_ok_for_arm (INTVAL (operands[3])))
  4368.     output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands);
  4369.   else
  4370.     output_asm_insn (\"add%d6\\t%0, %2, %3\", operands);
  4371.   if (which_alternative != 0)
  4372.     {
  4373.       if (GET_CODE (operands[1]) == MEM)
  4374.     output_asm_insn (\"ldr%D6\\t%0, %1\", operands);
  4375.       else
  4376.     output_asm_insn (\"mov%D6\\t%0, %1\", operands);
  4377.     }
  4378.   return \"\";
  4379. }
  4380. "
  4381. [(set_attr "conds" "clob")
  4382.  (set_attr "length" "8,12")])
  4383.  
  4384. (define_insn ""
  4385.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4386.     (if_then_else:SI (match_operator 6 "comparison_operator"
  4387.               [(match_operand:SI 4 "s_register_operand" "r,r")
  4388.                (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
  4389.              (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm")
  4390.              (plus:SI
  4391.               (match_operand:SI 2 "s_register_operand" "r,r")
  4392.               (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
  4393.    (clobber (reg 24))]
  4394.   ""
  4395.   "*
  4396. {
  4397.   if (GET_CODE (operands[5]) == CONST_INT
  4398.       && !const_ok_for_arm (INTVAL (operands[5])))
  4399.     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
  4400.   else
  4401.     output_asm_insn (\"cmp\\t%4, %5\", operands);
  4402.   if (GET_CODE (operands[3]) == CONST_INT
  4403.       && !const_ok_for_arm (INTVAL (operands[3])))
  4404.     output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands);
  4405.   else
  4406.     output_asm_insn (\"add%D6\\t%0, %2, %3\", operands);
  4407.   if (which_alternative != 0)
  4408.     {
  4409.       if (GET_CODE (operands[6]) == MEM)
  4410.     output_asm_insn (\"ldr%d6\\t%0, %1\", operands);
  4411.       else
  4412.     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
  4413.     }
  4414.   return \"\";
  4415. }
  4416. "
  4417. [(set_attr "conds" "clob")
  4418.  (set_attr "length" "8,12")])
  4419.  
  4420. (define_insn ""
  4421.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4422.     (if_then_else:SI (match_operator 5 "comparison_operator"
  4423.               [(match_operand:SI 3 "s_register_operand" "r,r")
  4424.                (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
  4425.              (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
  4426.              (not:SI
  4427.               (match_operand:SI 2 "s_register_operand" "r,r"))))
  4428.    (clobber (reg 24))]
  4429.   ""
  4430.   "#"
  4431. [(set_attr "conds" "clob")
  4432.  (set_attr "length" "8,12")])
  4433.  
  4434. (define_insn ""
  4435.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
  4436.     (if_then_else:SI 
  4437.      (match_operator 5 "comparison_operator"
  4438.       [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
  4439.        (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
  4440.      (not:SI
  4441.       (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
  4442.      (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
  4443.    (clobber (reg 24))]
  4444.   ""
  4445.   "@
  4446.    cmp\\t%3, %4\;mvn%d5\\t%0, %2
  4447.    cmn\\t%3, #%n4\;mvn%d5\\t%0, %2
  4448.    cmp\\t%3, %4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2
  4449.    cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;mvn%d5\\t%0, %2"
  4450. [(set_attr "conds" "clob")
  4451.  (set_attr "length" "8,8,12,12")])
  4452.  
  4453. (define_insn ""
  4454.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
  4455.     (if_then_else:SI
  4456.      (match_operator 6 "comparison_operator"
  4457.       [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
  4458.        (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
  4459.      (match_operator:SI 7 "shift_operator"
  4460.       [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
  4461.        (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])
  4462.      (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
  4463.    (clobber (reg 24))]
  4464.   ""
  4465.   "@
  4466.    cmp\\t%4, %5\;mov%d6\\t%0, %2%S7
  4467.    cmn\\t%4, #%n5\;mov%d6\\t%0, %2%S7
  4468.    cmp\\t%4, %5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7
  4469.    cmn\\t%4, #%n5\;mov%D6\\t%0, %1\;mov%d6\\t%0, %2%S7"
  4470. [(set_attr "conds" "clob")
  4471.  (set_attr "length" "8,8,12,12")])
  4472.  
  4473. (define_insn ""
  4474.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
  4475.     (if_then_else:SI
  4476.      (match_operator 6 "comparison_operator"
  4477.       [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
  4478.        (match_operand:SI 5 "arm_add_operand" "rI,L,rI,L")])
  4479.      (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
  4480.      (match_operator:SI 7 "shift_operator"
  4481.       [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
  4482.        (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM,rM")])))
  4483.    (clobber (reg 24))]
  4484.   ""
  4485.   "@
  4486.    cmp\\t%4, %5\;mov%D6\\t%0, %2%S7
  4487.    cmn\\t%4, #%n5\;mov%D6\\t%0, %2%S7
  4488.    cmp\\t%4, %5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7
  4489.    cmn\\t%4, #%n5\;mov%d6\\t%0, %1\;mov%D6\\t%0, %2%S7"
  4490. [(set_attr "conds" "clob")
  4491.  (set_attr "length" "8,8,12,12")])
  4492.  
  4493. (define_insn ""
  4494.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4495.     (if_then_else:SI
  4496.      (match_operator 7 "comparison_operator"
  4497.       [(match_operand:SI 5 "s_register_operand" "r,r")
  4498.        (match_operand:SI 6 "arm_add_operand" "rI,L")])
  4499.      (match_operator:SI 8 "shift_operator"
  4500.       [(match_operand:SI 1 "s_register_operand" "r,r")
  4501.        (match_operand:SI 2 "arm_rhs_operand" "rM,rM")])
  4502.      (match_operator:SI 9 "shift_operator"
  4503.       [(match_operand:SI 3 "s_register_operand" "r,r")
  4504.        (match_operand:SI 4 "arm_rhs_operand" "rI,rI")])))
  4505.    (clobber (reg 24))]
  4506.   ""
  4507.   "@
  4508.    cmp\\t%5, %6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9
  4509.    cmn\\t%5, #%n6\;mov%d7\\t%0, %1%S8\;mov%D7\\t%0, %3%S9"
  4510. [(set_attr "conds" "clob")
  4511.  (set_attr "length" "12")])
  4512.  
  4513. (define_insn ""
  4514.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4515.     (if_then_else:SI
  4516.      (match_operator 6 "comparison_operator"
  4517.       [(match_operand:SI 4 "s_register_operand" "r,r")
  4518.        (match_operand:SI 5 "arm_add_operand" "rI,L")])
  4519.      (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))
  4520.      (match_operator:SI 7 "shiftable_operator"
  4521.       [(match_operand:SI 2 "s_register_operand" "r,r")
  4522.        (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
  4523.    (clobber (reg 24))]
  4524.   ""
  4525.   "@
  4526.    cmp\\t%4, %5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3
  4527.    cmn\\t%4, #%n5\;mvn%d6\\t%0, %1\;%I7%D6\\t%0, %2, %3"
  4528. [(set_attr "conds" "clob")
  4529.  (set_attr "length" "12")])
  4530.  
  4531. (define_insn ""
  4532.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  4533.     (if_then_else:SI
  4534.      (match_operator 6 "comparison_operator"
  4535.       [(match_operand:SI 4 "s_register_operand" "r,r")
  4536.        (match_operand:SI 5 "arm_add_operand" "rI,L")])
  4537.      (match_operator:SI 7 "shiftable_operator"
  4538.       [(match_operand:SI 2 "s_register_operand" "r,r")
  4539.        (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
  4540.      (not:SI (match_operand:SI 1 "s_register_operand" "r,r"))))
  4541.    (clobber (reg 24))]
  4542.   ""
  4543.   "@
  4544.    cmp\\t%4, %5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3
  4545.    cmn\\t%4, #%n5\;mvn%D6\\t%0, %1\;%I7%d6\\t%0, %2, %3"
  4546. [(set_attr "conds" "clob")
  4547.  (set_attr "length" "12")])
  4548.  
  4549. (define_insn ""
  4550.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
  4551.     (if_then_else:SI
  4552.      (match_operator 5 "comparison_operator"
  4553.       [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
  4554.        (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
  4555.      (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))
  4556.      (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))
  4557.    (clobber (reg:CC 24))]
  4558.   ""
  4559.   "@
  4560.    cmp\\t%3, %4\;rsb%d5\\t%0, %2, #0
  4561.    cmn\\t%3, #%n4\;rsb%d5\\t%0, %2, #0
  4562.    cmp\\t%3, %4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0
  4563.    cmn\\t%3, #%n4\;mov%D5\\t%0, %1\;rsb%d5\\t%0, %2, #0"
  4564. [(set_attr "conds" "clob")
  4565.  (set_attr "length" "8,8,12,12")])
  4566.  
  4567. (define_insn ""
  4568.   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
  4569.     (if_then_else:SI
  4570.      (match_operator 5 "comparison_operator"
  4571.       [(match_operand:SI 3 "s_register_operand" "r,r,r,r")
  4572.        (match_operand:SI 4 "arm_add_operand" "rI,L,rI,L")])
  4573.      (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
  4574.      (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r"))))
  4575.    (clobber (reg:CC 24))]
  4576.   ""
  4577.   "@
  4578.    cmp\\t%3, %4\;rsb%D5\\t%0, %2, #0
  4579.    cmn\\t%3, #%n4\;rsb%D5\\t%0, %2, #0
  4580.    cmp\\t%3, %4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0
  4581.    cmn\\t%3, #%n4\;mov%d5\\t%0, %1\;rsb%D5\\t%0, %2, #0"
  4582. [(set_attr "conds" "clob")
  4583.  (set_attr "length" "8,8,12,12")])
  4584.  
  4585. (define_insn ""
  4586.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  4587.     (match_operator:SI 1 "shiftable_operator"
  4588.      [(match_operand:SI 2 "memory_operand" "m")
  4589.       (match_operand:SI 3 "memory_operand" "m")]))
  4590.    (clobber (match_scratch:SI 4 "=r"))]
  4591.   "adjacent_mem_locations (operands[2], operands[3])"
  4592.   "*
  4593. {
  4594.   rtx ldm[3];
  4595.   rtx arith[4];
  4596.   int val1 = 0, val2 = 0;
  4597.  
  4598.   if (REGNO (operands[0]) > REGNO (operands[4]))
  4599.     {
  4600.       ldm[1] = operands[4];
  4601.       ldm[2] = operands[0];
  4602.     }
  4603.   else
  4604.     {
  4605.       ldm[1] = operands[0];
  4606.       ldm[2] = operands[4];
  4607.     }
  4608.   if (GET_CODE (XEXP (operands[2], 0)) != REG)
  4609.     val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
  4610.   if (GET_CODE (XEXP (operands[3], 0)) != REG)
  4611.     val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
  4612.   arith[0] = operands[0];
  4613.   arith[3] = operands[1];
  4614.   if (val1 < val2)
  4615.     {
  4616.       arith[1] = ldm[1];
  4617.       arith[2] = ldm[2];
  4618.     }
  4619.   else
  4620.     {
  4621.       arith[1] = ldm[2];
  4622.       arith[2] = ldm[1];
  4623.     }
  4624.   if (val1 && val2)
  4625.     {
  4626.       rtx ops[3];
  4627.       ldm[0] = ops[0] = operands[4];
  4628.       ops[1] = XEXP (XEXP (operands[2], 0), 0);
  4629.       ops[2] = XEXP (XEXP (operands[2], 0), 1);
  4630.       output_add_immediate (ops);
  4631.       if (val1 < val2)
  4632.     output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
  4633.       else
  4634.     output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
  4635.     }
  4636.   else if (val1)
  4637.     {
  4638.       ldm[0] = XEXP (operands[3], 0);
  4639.       if (val1 < val2)
  4640.     output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
  4641.       else
  4642.     output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
  4643.     }
  4644.   else
  4645.     {
  4646.       ldm[0] = XEXP (operands[2], 0);
  4647.       if (val1 < val2)
  4648.     output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
  4649.       else
  4650.     output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
  4651.     }
  4652.   output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
  4653.   return \"\";
  4654. }
  4655. "
  4656. [(set_attr "length" "12")
  4657.  (set_attr "type" "load")])
  4658.  
  4659. ;; the arm can support extended pre-inc instructions
  4660.  
  4661. ;; In all these cases, we use operands 0 and 1 for the register being
  4662. ;; incremented because those are the operands that local-alloc will
  4663. ;; tie and these are the pair most likely to be tieable (and the ones
  4664. ;; that will benefit the most).
  4665.  
  4666. ;; We reject the frame pointer if it occurs anywhere in these patterns since
  4667. ;; elimination will cause too many headaches.
  4668.  
  4669. (define_insn ""
  4670.   [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  4671.              (match_operand:SI 2 "index_operand" "rJ")))
  4672.     (match_operand:QI 3 "s_register_operand" "r"))
  4673.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4674.     (plus:SI (match_dup 1) (match_dup 2)))]
  4675.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4676.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4677.    && (GET_CODE (operands[2]) != REG
  4678.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4679.   "str%?b\\t%3, [%0, %2]!"
  4680. [(set_attr "type" "store1")])
  4681.  
  4682. (define_insn ""
  4683.   [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4684.               (match_operand:SI 2 "s_register_operand" "r")))
  4685.     (match_operand:QI 3 "s_register_operand" "r"))
  4686.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4687.     (minus:SI (match_dup 1) (match_dup 2)))]
  4688.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4689.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4690.    && (GET_CODE (operands[2]) != REG
  4691.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4692.   "str%?b\\t%3, [%0, -%2]!"
  4693. [(set_attr "type" "store1")])
  4694.  
  4695. (define_insn ""
  4696.   [(set (match_operand:QI 3 "s_register_operand" "=r")
  4697.     (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  4698.              (match_operand:SI 2 "index_operand" "rJ"))))
  4699.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4700.     (plus:SI (match_dup 1) (match_dup 2)))]
  4701.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4702.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4703.    && (GET_CODE (operands[2]) != REG
  4704.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4705.   "ldr%?b\\t%3, [%0, %2]!"
  4706. [(set_attr "type" "load")])
  4707.  
  4708. (define_insn ""
  4709.   [(set (match_operand:QI 3 "s_register_operand" "=r")
  4710.     (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4711.               (match_operand:SI 2 "s_register_operand" "r"))))
  4712.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4713.     (minus:SI (match_dup 1) (match_dup 2)))]
  4714.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4715.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4716.    && (GET_CODE (operands[2]) != REG
  4717.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4718.   "ldr%?b\\t%3, [%0, -%2]!"
  4719. [(set_attr "type" "load")])
  4720.  
  4721. (define_insn ""
  4722.   [(set (match_operand:SI 3 "s_register_operand" "=r")
  4723.     (zero_extend:SI
  4724.      (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  4725.               (match_operand:SI 2 "index_operand" "rJ")))))
  4726.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4727.     (plus:SI (match_dup 1) (match_dup 2)))]
  4728.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4729.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4730.    && (GET_CODE (operands[2]) != REG
  4731.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4732.   "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
  4733. [(set_attr "type" "load")])
  4734.  
  4735. (define_insn ""
  4736.   [(set (match_operand:SI 3 "s_register_operand" "=r")
  4737.     (zero_extend:SI
  4738.      (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4739.                (match_operand:SI 2 "s_register_operand" "r")))))
  4740.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4741.     (minus:SI (match_dup 1) (match_dup 2)))]
  4742.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4743.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4744.    && (GET_CODE (operands[2]) != REG
  4745.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4746.   "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
  4747. [(set_attr "type" "load")])
  4748.  
  4749. (define_insn ""
  4750.   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  4751.              (match_operand:SI 2 "index_operand" "rJ")))
  4752.     (match_operand:SI 3 "s_register_operand" "r"))
  4753.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4754.     (plus:SI (match_dup 1) (match_dup 2)))]
  4755.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4756.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4757.    && (GET_CODE (operands[2]) != REG
  4758.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4759.   "str%?\\t%3, [%0, %2]!"
  4760. [(set_attr "type" "store1")])
  4761.  
  4762. (define_insn ""
  4763.   [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4764.               (match_operand:SI 2 "s_register_operand" "r")))
  4765.     (match_operand:SI 3 "s_register_operand" "r"))
  4766.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4767.     (minus:SI (match_dup 1) (match_dup 2)))]
  4768.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4769.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4770.    && (GET_CODE (operands[2]) != REG
  4771.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4772.   "str%?\\t%3, [%0, -%2]!"
  4773. [(set_attr "type" "store1")])
  4774.  
  4775. (define_insn ""
  4776.   [(set (match_operand:SI 3 "s_register_operand" "=r")
  4777.     (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  4778.              (match_operand:SI 2 "index_operand" "rJ"))))
  4779.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4780.     (plus:SI (match_dup 1) (match_dup 2)))]
  4781.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4782.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4783.    && (GET_CODE (operands[2]) != REG
  4784.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4785.   "ldr%?\\t%3, [%0, %2]!"
  4786. [(set_attr "type" "load")])
  4787.  
  4788. (define_insn ""
  4789.   [(set (match_operand:SI 3 "s_register_operand" "=r")
  4790.     (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4791.               (match_operand:SI 2 "s_register_operand" "r"))))
  4792.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4793.     (minus:SI (match_dup 1) (match_dup 2)))]
  4794.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4795.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4796.    && (GET_CODE (operands[2]) != REG
  4797.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4798.   "ldr%?\\t%3, [%0, -%2]!"
  4799. [(set_attr "type" "load")])
  4800.  
  4801. (define_insn ""
  4802.   [(set (match_operand:HI 3 "s_register_operand" "=r")
  4803.     (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
  4804.              (match_operand:SI 2 "index_operand" "rJ"))))
  4805.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4806.     (plus:SI (match_dup 1) (match_dup 2)))]
  4807.   "(! BYTES_BIG_ENDIAN)
  4808.    && ! TARGET_SHORT_BY_BYTES
  4809.    && REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4810.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4811.    && (GET_CODE (operands[2]) != REG
  4812.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4813.   "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
  4814. [(set_attr "type" "load")])
  4815.  
  4816. (define_insn ""
  4817.   [(set (match_operand:HI 3 "s_register_operand" "=r")
  4818.     (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4819.               (match_operand:SI 2 "s_register_operand" "r"))))
  4820.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4821.     (minus:SI (match_dup 1) (match_dup 2)))]
  4822.   "(!BYTES_BIG_ENDIAN)
  4823.    && ! TARGET_SHORT_BY_BYTES
  4824.    && REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4825.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4826.    && (GET_CODE (operands[2]) != REG
  4827.        || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
  4828.   "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
  4829. [(set_attr "type" "load")])
  4830.  
  4831. (define_insn ""
  4832.   [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
  4833.               [(match_operand:SI 3 "s_register_operand" "r")
  4834.                (match_operand:SI 4 "const_shift_operand" "n")])
  4835.              (match_operand:SI 1 "s_register_operand" "0")))
  4836.     (match_operand:QI 5 "s_register_operand" "r"))
  4837.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4838.     (plus:SI (match_op_dup 2 [(match_dup 3)    (match_dup 4)])
  4839.          (match_dup 1)))]
  4840.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4841.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4842.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  4843.   "str%?b\\t%5, [%0, %3%S2]!"
  4844. [(set_attr "type" "store1")])
  4845.  
  4846. (define_insn ""
  4847.   [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4848.               (match_operator:SI 2 "shift_operator"
  4849.                [(match_operand:SI 3 "s_register_operand" "r")
  4850.                 (match_operand:SI 4 "const_shift_operand" "n")])))
  4851.     (match_operand:QI 5 "s_register_operand" "r"))
  4852.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4853.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  4854.                          (match_dup 4)])))]
  4855.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4856.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4857.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  4858.   "str%?b\\t%5, [%0, -%3%S2]!"
  4859. [(set_attr "type" "store1")])
  4860.  
  4861. (define_insn ""
  4862.   [(set (match_operand:QI 5 "s_register_operand" "=r")
  4863.     (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
  4864.               [(match_operand:SI 3 "s_register_operand" "r")
  4865.                (match_operand:SI 4 "const_shift_operand" "n")])
  4866.              (match_operand:SI 1 "s_register_operand" "0"))))
  4867.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4868.     (plus:SI (match_op_dup 2 [(match_dup 3)    (match_dup 4)])
  4869.          (match_dup 1)))]
  4870.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4871.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4872.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  4873.   "ldr%?b\\t%5, [%0, %3%S2]!"
  4874. [(set_attr "type" "load")])
  4875.  
  4876. (define_insn ""
  4877.   [(set (match_operand:QI 5 "s_register_operand" "=r")
  4878.     (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4879.               (match_operator:SI 2 "shift_operator"
  4880.                [(match_operand:SI 3 "s_register_operand" "r")
  4881.                 (match_operand:SI 4 "const_shift_operand" "n")]))))
  4882.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4883.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  4884.                          (match_dup 4)])))]
  4885.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4886.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4887.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  4888.   "ldr%?b\\t%5, [%0, -%3%S2]!"
  4889. [(set_attr "type" "load")])
  4890.  
  4891. (define_insn ""
  4892.   [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
  4893.               [(match_operand:SI 3 "s_register_operand" "r")
  4894.                (match_operand:SI 4 "const_shift_operand" "n")])
  4895.              (match_operand:SI 1 "s_register_operand" "0")))
  4896.     (match_operand:SI 5 "s_register_operand" "r"))
  4897.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4898.     (plus:SI (match_op_dup 2 [(match_dup 3)    (match_dup 4)])
  4899.          (match_dup 1)))]
  4900.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4901.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4902.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  4903.   "str%?\\t%5, [%0, %3%S2]!"
  4904. [(set_attr "type" "store1")])
  4905.  
  4906. (define_insn ""
  4907.   [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4908.               (match_operator:SI 2 "shift_operator"
  4909.                [(match_operand:SI 3 "s_register_operand" "r")
  4910.                 (match_operand:SI 4 "const_shift_operand" "n")])))
  4911.     (match_operand:SI 5 "s_register_operand" "r"))
  4912.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4913.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  4914.                          (match_dup 4)])))]
  4915.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4916.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4917.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  4918.   "str%?\\t%5, [%0, -%3%S2]!"
  4919. [(set_attr "type" "store1")])
  4920.  
  4921. (define_insn ""
  4922.   [(set (match_operand:SI 5 "s_register_operand" "=r")
  4923.     (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
  4924.               [(match_operand:SI 3 "s_register_operand" "r")
  4925.                (match_operand:SI 4 "const_shift_operand" "n")])
  4926.              (match_operand:SI 1 "s_register_operand" "0"))))
  4927.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4928.     (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
  4929.          (match_dup 1)))]
  4930.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4931.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4932.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  4933.   "ldr%?\\t%5, [%0, %3%S2]!"
  4934. [(set_attr "type" "load")])
  4935.  
  4936. (define_insn ""
  4937.   [(set (match_operand:SI 5 "s_register_operand" "=r")
  4938.     (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4939.               (match_operator:SI 2 "shift_operator"
  4940.                [(match_operand:SI 3 "s_register_operand" "r")
  4941.                 (match_operand:SI 4 "const_shift_operand" "n")]))))
  4942.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4943.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  4944.                          (match_dup 4)])))]
  4945.   "REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4946.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4947.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  4948.   "ldr%?\\t%5, [%0, -%3%S2]!"
  4949. [(set_attr "type" "load")])
  4950.  
  4951. (define_insn ""
  4952.   [(set (match_operand:HI 5 "s_register_operand" "=r")
  4953.     (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
  4954.               [(match_operand:SI 3 "s_register_operand" "r")
  4955.                (match_operand:SI 4 "const_shift_operand" "n")])
  4956.              (match_operand:SI 1 "s_register_operand" "0"))))
  4957.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4958.     (plus:SI (match_op_dup 2 [(match_dup 3)    (match_dup 4)])
  4959.          (match_dup 1)))]
  4960.   "(! BYTES_BIG_ENDIAN)
  4961.    && ! TARGET_SHORT_BY_BYTES
  4962.    && REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4963.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4964.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  4965.   "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
  4966. [(set_attr "type" "load")])
  4967.  
  4968. (define_insn ""
  4969.   [(set (match_operand:HI 5 "s_register_operand" "=r")
  4970.     (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
  4971.               (match_operator:SI 2 "shift_operator"
  4972.                [(match_operand:SI 3 "s_register_operand" "r")
  4973.                 (match_operand:SI 4 "const_shift_operand" "n")]))))
  4974.    (set (match_operand:SI 0 "s_register_operand" "=r")
  4975.     (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
  4976.                          (match_dup 4)])))]
  4977.   "(! BYTES_BIG_ENDIAN)
  4978.    && ! TARGET_SHORT_BY_BYTES
  4979.    && REGNO (operands[0]) != FRAME_POINTER_REGNUM
  4980.    && REGNO (operands[1]) != FRAME_POINTER_REGNUM
  4981.    && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
  4982.   "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
  4983. [(set_attr "type" "load")])
  4984.  
  4985. ; It can also support extended post-inc expressions, but combine doesn't
  4986. ; try these....
  4987. ; It doesn't seem worth adding peepholes for anything but the most common
  4988. ; cases since, unlike combine, the increment must immediately follow the load
  4989. ; for this pattern to match.
  4990. ; When loading we must watch to see that the base register isn't trampled by
  4991. ; the load.  In such cases this isn't a post-inc expression.
  4992.  
  4993. (define_peephole
  4994.   [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
  4995.     (match_operand:QI 2 "s_register_operand" "r"))
  4996.    (set (match_dup 0)
  4997.     (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
  4998.   ""
  4999.   "str%?b\\t%2, [%0], %1")
  5000.  
  5001. (define_peephole
  5002.   [(set (match_operand:QI 0 "s_register_operand" "=r")
  5003.     (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
  5004.    (set (match_dup 1)
  5005.     (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
  5006.   "REGNO(operands[0]) != REGNO(operands[1])
  5007.    && (GET_CODE (operands[2]) != REG
  5008.        || REGNO(operands[0]) != REGNO (operands[2]))"
  5009.   "ldr%?b\\t%0, [%1], %2")
  5010.  
  5011. (define_peephole
  5012.   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
  5013.     (match_operand:SI 2 "s_register_operand" "r"))
  5014.    (set (match_dup 0)
  5015.     (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
  5016.   ""
  5017.   "str%?\\t%2, [%0], %1")
  5018.  
  5019. (define_peephole
  5020.   [(set (match_operand:HI 0 "s_register_operand" "=r")
  5021.     (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
  5022.    (set (match_dup 1)
  5023.     (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
  5024.   "(! BYTES_BIG_ENDIAN)
  5025.    && ! TARGET_SHORT_BY_BYTES
  5026.    && REGNO(operands[0]) != REGNO(operands[1])
  5027.    && (GET_CODE (operands[2]) != REG
  5028.        || REGNO(operands[0]) != REGNO (operands[2]))"
  5029.   "ldr%?\\t%0, [%1], %2\\t%@ loadhi")
  5030.  
  5031. (define_peephole
  5032.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5033.     (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
  5034.    (set (match_dup 1)
  5035.     (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
  5036.   "REGNO(operands[0]) != REGNO(operands[1])
  5037.    && (GET_CODE (operands[2]) != REG
  5038.        || REGNO(operands[0]) != REGNO (operands[2]))"
  5039.   "ldr%?\\t%0, [%1], %2")
  5040.  
  5041. (define_peephole
  5042.   [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
  5043.              (match_operand:SI 1 "index_operand" "rJ")))
  5044.     (match_operand:QI 2 "s_register_operand" "r"))
  5045.    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
  5046.   ""
  5047.   "str%?b\\t%2, [%0, %1]!")
  5048.  
  5049. (define_peephole
  5050.   [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
  5051.               [(match_operand:SI 0 "s_register_operand" "r")
  5052.                (match_operand:SI 1 "const_int_operand" "n")])
  5053.              (match_operand:SI 2 "s_register_operand" "+r")))
  5054.     (match_operand:QI 3 "s_register_operand" "r"))
  5055.    (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
  5056.                    (match_dup 2)))]
  5057.   ""
  5058.   "str%?b\\t%3, [%2, %0%S4]!")
  5059.  
  5060. ; This pattern is never tried by combine, so do it as a peephole
  5061.  
  5062. (define_peephole
  5063.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5064.     (match_operand:SI 1 "s_register_operand" "r"))
  5065.    (set (match_operand 2 "cc_register" "")
  5066.     (compare (match_dup 1) (const_int 0)))]
  5067.   ""
  5068.   "sub%?s\\t%0, %1, #0"
  5069. [(set_attr "conds" "set")])
  5070.  
  5071. ; Peepholes to spot possible load- and store-multiples, if the ordering is
  5072. ; reversed, check that the memory references aren't volatile.
  5073.  
  5074. (define_peephole
  5075.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5076.         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5077.                          (const_int 12))))
  5078.    (set (match_operand:SI 2 "s_register_operand" "=r")
  5079.         (mem:SI (plus:SI (match_dup 1) (const_int 8))))
  5080.    (set (match_operand:SI 3 "s_register_operand" "=r")
  5081.         (mem:SI (plus:SI (match_dup 1) (const_int 4))))
  5082.    (set (match_operand:SI 4 "s_register_operand" "=r")
  5083.         (mem:SI (match_dup 1)))]
  5084.   "REGNO (operands[0]) > REGNO (operands[2])
  5085.    && REGNO (operands[2]) > REGNO (operands[3])
  5086.    && REGNO (operands[3]) > REGNO (operands[4])
  5087.    && !(REGNO (operands[1]) == REGNO (operands[0])
  5088.        || REGNO (operands[1]) == REGNO (operands[2])
  5089.        || REGNO (operands[1]) == REGNO (operands[3])
  5090.        || REGNO (operands[1]) == REGNO (operands[4]))
  5091.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
  5092.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
  5093.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
  5094.                      (prev_nonnote_insn (insn)))))
  5095.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
  5096.                      (prev_nonnote_insn 
  5097.                       (prev_nonnote_insn (insn))))))"
  5098.   "ldm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole ldm")
  5099.  
  5100. (define_peephole
  5101.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5102.         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5103.                          (const_int 8))))
  5104.    (set (match_operand:SI 2 "s_register_operand" "=r")
  5105.         (mem:SI (plus:SI (match_dup 1) (const_int 4))))
  5106.    (set (match_operand:SI 3 "s_register_operand" "=r")
  5107.         (mem:SI (match_dup 1)))]
  5108.   "REGNO (operands[0]) >  REGNO (operands[2])
  5109.    && REGNO (operands[2]) > REGNO (operands[3])
  5110.    && !(REGNO (operands[1]) == REGNO (operands[0])
  5111.        || REGNO (operands[1]) == REGNO (operands[2])
  5112.        || REGNO (operands[1]) == REGNO (operands[3]))
  5113.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
  5114.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))
  5115.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn
  5116.                      (prev_nonnote_insn (insn)))))"
  5117.   "ldm%?ia\\t%1, {%3, %2, %0}\\t%@ phole ldm")
  5118.  
  5119. (define_peephole
  5120.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5121.         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5122.                          (const_int 4))))
  5123.    (set (match_operand:SI 2 "s_register_operand" "=r")
  5124.         (mem:SI (match_dup 1)))]
  5125.   "REGNO (operands[0]) > REGNO (operands[2])
  5126.    && !(REGNO (operands[1]) == REGNO (operands[0])
  5127.        || REGNO (operands[1]) == REGNO (operands[2]))
  5128.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn)))
  5129.    && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))"
  5130.   "ldm%?ia\\t%1, {%2, %0}\\t%@ phole ldm")
  5131.  
  5132. (define_peephole
  5133.   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5134.                          (const_int 12)))
  5135.         (match_operand:SI 0 "s_register_operand" "r"))
  5136.    (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
  5137.         (match_operand:SI 2 "s_register_operand" "r"))
  5138.    (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
  5139.         (match_operand:SI 3 "s_register_operand" "r"))
  5140.    (set (mem:SI (match_dup 1))
  5141.         (match_operand:SI 4 "s_register_operand" "r"))]
  5142.   "REGNO (operands[0]) >  REGNO (operands[2])
  5143.    && REGNO (operands[2]) > REGNO (operands[3])
  5144.    && REGNO (operands[3]) > REGNO (operands[4])
  5145.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
  5146.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
  5147.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
  5148.                       (prev_nonnote_insn (insn)))))
  5149.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
  5150.                       (prev_nonnote_insn 
  5151.                        (prev_nonnote_insn (insn))))))"
  5152.   "stm%?ia\\t%1, {%4, %3, %2, %0}\\t%@ phole stm")
  5153.  
  5154. (define_peephole
  5155.   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5156.                          (const_int 8)))
  5157.         (match_operand:SI 0 "s_register_operand" "r"))
  5158.    (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
  5159.         (match_operand:SI 2 "s_register_operand" "r"))
  5160.    (set (mem:SI (match_dup 1))
  5161.         (match_operand:SI 3 "s_register_operand" "r"))]
  5162.   "REGNO (operands[0]) >  REGNO (operands[2])
  5163.    && REGNO (operands[2]) > REGNO (operands[3])
  5164.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
  5165.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))
  5166.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn
  5167.                       (prev_nonnote_insn (insn)))))"
  5168.   "stm%?ia\\t%1, {%3, %2, %0}\\t%@ phole stm")
  5169.  
  5170. (define_peephole
  5171.   [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
  5172.                          (const_int 4)))
  5173.         (match_operand:SI 0 "s_register_operand" "r"))
  5174.    (set (mem:SI (match_dup 1))
  5175.         (match_operand:SI 2 "s_register_operand" "r"))]
  5176.   "REGNO (operands[0]) >  REGNO (operands[2])
  5177.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn)))
  5178.    && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))"
  5179.   "stm%?ia\\t%1, {%2, %0}\\t%@ phole stm")
  5180.  
  5181. ;; A call followed by return can be replaced by restoring the regs and
  5182. ;; jumping to the subroutine, provided we aren't passing the address of
  5183. ;; any of our local variables.  If we call alloca then this is unsafe
  5184. ;; since restoring the frame frees the memory, which is not what we want.
  5185. ;; Sometimes the return might have been targeted by the final prescan:
  5186. ;; if so then emit a propper return insn as well.
  5187. ;; Unfortunately, if the frame pointer is required, we don't know if the
  5188. ;; current function has any implicit stack pointer adjustments that will 
  5189. ;; be restored by the return: we can't therefore do a tail call.
  5190. ;; Another unfortunate that we can't handle is if current_function_args_size
  5191. ;; is non-zero: in this case elimination of the argument pointer assumed
  5192. ;; that lr was pushed onto the stack, so eliminating upsets the offset
  5193. ;; calculations.
  5194.  
  5195. (define_peephole
  5196.   [(parallel [(call (mem:SI (match_operand:SI 0 "" "i"))
  5197.               (match_operand:SI 1 "general_operand" "g"))
  5198.             (clobber (reg:SI 14))])
  5199.    (return)]
  5200.   "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN
  5201.     && !get_frame_size () && !current_function_calls_alloca
  5202.     && !frame_pointer_needed && !current_function_args_size)"
  5203.   "*
  5204. {
  5205.   extern rtx arm_target_insn;
  5206.   extern int arm_ccfsm_state, arm_current_cc;
  5207.  
  5208.   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
  5209.   {
  5210.     arm_current_cc ^= 1;
  5211.     output_return_instruction (NULL, TRUE);
  5212.     arm_ccfsm_state = 0;
  5213.     arm_target_insn = NULL;
  5214.   }
  5215.  
  5216.   output_return_instruction (NULL, FALSE);
  5217.   return \"b%?\\t%a0\";
  5218. }"
  5219. [(set (attr "conds")
  5220.       (if_then_else (eq_attr "cpu" "arm6")
  5221.             (const_string "clob")
  5222.             (const_string "nocond")))
  5223.  (set_attr "length" "8")])
  5224.  
  5225. (define_peephole
  5226.   [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
  5227.            (call (mem:SI (match_operand:SI 1 "" "i"))
  5228.              (match_operand:SI 2 "general_operand" "g")))
  5229.           (clobber (reg:SI 14))])
  5230.    (return)]
  5231.   "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
  5232.     && !get_frame_size () && !current_function_calls_alloca
  5233.     && !frame_pointer_needed && !current_function_args_size)"
  5234.   "*
  5235. {
  5236.   extern rtx arm_target_insn;
  5237.   extern int arm_ccfsm_state, arm_current_cc;
  5238.  
  5239.   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
  5240.   {
  5241.     arm_current_cc ^= 1;
  5242.     output_return_instruction (NULL, TRUE);
  5243.     arm_ccfsm_state = 0;
  5244.     arm_target_insn = NULL;
  5245.   }
  5246.  
  5247.   output_return_instruction (NULL, FALSE);
  5248.   return \"b%?\\t%a1\";
  5249. }"
  5250. [(set (attr "conds")
  5251.       (if_then_else (eq_attr "cpu" "arm6")
  5252.             (const_string "clob")
  5253.             (const_string "nocond")))
  5254.  (set_attr "length" "8")])
  5255.  
  5256. ;; As above but when this function is not void, we must be returning the
  5257. ;; result of the called subroutine.
  5258.  
  5259. (define_peephole
  5260.   [(parallel [(set (match_operand 0 "s_register_operand" "=rf")
  5261.            (call (mem:SI (match_operand:SI 1 "" "i"))
  5262.              (match_operand:SI 2 "general_operand" "g")))
  5263.           (clobber (reg:SI 14))])
  5264.    (use (match_dup 0))
  5265.    (return)]
  5266.   "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN
  5267.     && !get_frame_size () && !current_function_calls_alloca
  5268.     && !frame_pointer_needed && !current_function_args_size)"
  5269.   "*
  5270. {
  5271.   extern rtx arm_target_insn;
  5272.   extern int arm_ccfsm_state, arm_current_cc;
  5273.  
  5274.   if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn))
  5275.   {
  5276.     arm_current_cc ^= 1;
  5277.     output_return_instruction (NULL, TRUE);
  5278.     arm_ccfsm_state = 0;
  5279.     arm_target_insn = NULL;
  5280.   }
  5281.  
  5282.   output_return_instruction (NULL, FALSE);
  5283.   return \"b%?\\t%a1\";
  5284. }"
  5285. [(set (attr "conds")
  5286.       (if_then_else (eq_attr "cpu" "arm6")
  5287.             (const_string "clob")
  5288.             (const_string "nocond")))
  5289.  (set_attr "length" "8")])
  5290.  
  5291. ;; If calling a subroutine and then jumping back to somewhere else, but not
  5292. ;; too far away, then we can set the link register with the branch address
  5293. ;; and jump direct to the subroutine.  On return from the subroutine
  5294. ;; execution continues at the branch; this avoids a prefetch stall.
  5295. ;; We use the length attribute (via short_branch ()) to establish whether or
  5296. ;; not this is possible, this is the same asthe sparc does.
  5297.  
  5298. (define_peephole
  5299.   [(parallel[(call (mem:SI (match_operand:SI 0 "" "i"))
  5300.                    (match_operand:SI 1 "general_operand" "g"))
  5301.              (clobber (reg:SI 14))])
  5302.    (set (pc)
  5303.         (label_ref (match_operand 2 "" "")))]
  5304.   "0 && GET_CODE (operands[0]) == SYMBOL_REF 
  5305.    && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
  5306.    && arm_insn_not_targeted (insn)"
  5307.   "*
  5308. {
  5309.   int backward = arm_backwards_branch (INSN_UID (insn),
  5310.                        INSN_UID (operands[2]));
  5311.  
  5312. #if 0
  5313.   /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
  5314.    * above, leaving it out means that the code will still run on an arm 2 or 3
  5315.    */
  5316.   if (TARGET_6)
  5317.     {
  5318.       if (backward)
  5319.     output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l2)\", operands);
  5320.       else
  5321.     output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l2 - . -8)\", operands);
  5322.     }
  5323.   else
  5324. #endif
  5325.     {
  5326.       output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
  5327.       if (backward)
  5328.     output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l2)\", operands);
  5329.       else
  5330.     output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l2 - . -4)\", operands);
  5331.     }
  5332.   return \"b%?\\t%a0\";
  5333. }"
  5334. [(set (attr "conds")
  5335.       (if_then_else (eq_attr "cpu" "arm6")
  5336.             (const_string "clob")
  5337.             (const_string "nocond")))
  5338.  (set (attr "length")
  5339.       (if_then_else (eq_attr "cpu" "arm6")
  5340.             (const_int 8)
  5341.             (const_int 12)))])
  5342.  
  5343. (define_peephole
  5344.   [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r")
  5345.           (call (mem:SI (match_operand:SI 1 "" "i"))
  5346.                         (match_operand:SI 2 "general_operand" "g")))
  5347.              (clobber (reg:SI 14))])
  5348.    (set (pc)
  5349.         (label_ref (match_operand 3 "" "")))]
  5350.   "0 && GET_CODE (operands[0]) == SYMBOL_REF
  5351.    && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
  5352.    && arm_insn_not_targeted (insn)"
  5353.   "*
  5354. {
  5355.   int backward = arm_backwards_branch (INSN_UID (insn),
  5356.                        INSN_UID (operands[3]));
  5357.  
  5358. #if 0
  5359.   /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or
  5360.    * above, leaving it out means that the code will still run on an arm 2 or 3
  5361.    */
  5362.   if (TARGET_6)
  5363.     {
  5364.       if (backward)
  5365.     output_asm_insn (\"sub%?\\t%|lr, %|pc, #(8 + . -%l3)\", operands);
  5366.       else
  5367.     output_asm_insn (\"add%?\\t%|lr, %|pc, #(%l3 - . -8)\", operands);
  5368.     }
  5369.   else
  5370. #endif
  5371.     {
  5372.       output_asm_insn (\"mov%?\\t%|lr, %|pc\\t%@ protect cc\", operands);
  5373.       if (backward)
  5374.     output_asm_insn (\"sub%?\\t%|lr, %|lr, #(4 + . -%l3)\", operands);
  5375.       else
  5376.     output_asm_insn (\"add%?\\t%|lr, %|lr, #(%l3 - . -4)\", operands);
  5377.     }
  5378.   return \"b%?\\t%a1\";
  5379. }"
  5380. [(set (attr "conds")
  5381.       (if_then_else (eq_attr "cpu" "arm6")
  5382.             (const_string "clob")
  5383.             (const_string "nocond")))
  5384.  (set (attr "length")
  5385.       (if_then_else (eq_attr "cpu" "arm6")
  5386.             (const_int 8)
  5387.             (const_int 12)))])
  5388.  
  5389. (define_split
  5390.   [(set (pc)
  5391.     (if_then_else (match_operator 0 "comparison_operator"
  5392.                [(match_operator:SI 1 "shift_operator"
  5393.              [(match_operand:SI 2 "s_register_operand" "r")
  5394.               (match_operand:SI 3 "reg_or_int_operand" "rM")])
  5395.             (match_operand:SI 4 "s_register_operand" "r")])
  5396.               (label_ref (match_operand 5 "" ""))
  5397.               (pc)))
  5398.    (clobber (reg 24))]
  5399.   ""
  5400.   [(set (reg:CC 24)
  5401.     (compare:CC (match_dup 4)
  5402.             (match_op_dup 1 [(match_dup 2) (match_dup 3)])))
  5403.    (set (pc)
  5404.     (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)])
  5405.               (label_ref (match_dup 5))
  5406.               (pc)))]
  5407.   "
  5408.   operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode,
  5409.              operands[1], operands[2]);
  5410. ")
  5411.  
  5412. (define_split
  5413.   [(set (match_operand:SI 0 "s_register_operand" "")
  5414.     (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
  5415.                (const_int 0))
  5416.         (neg:SI (match_operator:SI 2 "comparison_operator"
  5417.              [(match_operand:SI 3 "s_register_operand" "")
  5418.               (match_operand:SI 4 "arm_rhs_operand" "")]))))
  5419.    (clobber (match_operand:SI 5 "s_register_operand" ""))]
  5420.   ""
  5421.   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
  5422.    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
  5423.                   (match_dup 5)))]
  5424.   "")
  5425.  
  5426. ;; This pattern can be used because cc_noov mode implies that the following
  5427. ;; branch will be an equality (EQ or NE), so the sign extension is not
  5428. ;; needed.  Combine doesn't eliminate these because by the time it sees the
  5429. ;; branch it no-longer knows that the data came from memory.
  5430.  
  5431. (define_insn ""
  5432.   [(set (reg:CC_NOOV 24)
  5433.     (compare:CC_NOOV
  5434.      (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0)
  5435.             (const_int 24))
  5436.      (match_operand 1 "immediate_operand" "I")))
  5437.    (clobber (match_scratch:SI 2 "=r"))]
  5438.   "((unsigned long) INTVAL (operands[1]))
  5439.    == (((unsigned long) INTVAL (operands[1])) >> 24) << 24"
  5440.   "*
  5441.   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
  5442.   output_asm_insn (\"ldr%?b\\t%2, %0\", operands);
  5443.   output_asm_insn (\"cmp%?\\t%2, %1\", operands);
  5444.   return \"\";
  5445. "
  5446. [(set_attr "conds" "set")
  5447.  (set_attr "length" "8")
  5448.  (set_attr "type" "load")])
  5449.  
  5450. (define_expand "prologue"
  5451.   [(clobber (const_int 0))]
  5452.   ""
  5453.   "
  5454.   arm_expand_prologue ();
  5455.   DONE;
  5456. ")
  5457.  
  5458. ;; This split is only used during output to reduce the number of patterns
  5459. ;; that need assembler instructions adding to them.  We allowed the setting
  5460. ;; of the conditions to be implicit during rtl generation so that
  5461. ;; the conditional compare patterns would work.  However this conflicts to
  5462. ;; some extend with the conditional data operations, so we have to split them
  5463. ;; up again here.
  5464.  
  5465. (define_split
  5466.   [(set (match_operand:SI 0 "s_register_operand" "")
  5467.     (if_then_else:SI (match_operator 1 "comparison_operator"
  5468.               [(match_operand 2 "" "") (match_operand 3 "" "")])
  5469.              (match_operand 4 "" "")
  5470.              (match_operand 5 "" "")))
  5471.    (clobber (reg 24))]
  5472.   "reload_completed"
  5473.   [(set (match_dup 6) (match_dup 7))
  5474.    (set (match_dup 0) 
  5475.     (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
  5476.              (match_dup 4)
  5477.              (match_dup 5)))]
  5478.   "
  5479. {
  5480.   enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2],
  5481.                        operands[3]);
  5482.  
  5483.   operands[6] = gen_rtx (REG, mode, 24);
  5484.   operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
  5485. }
  5486. ")
  5487.  
  5488.  
  5489. (define_insn ""
  5490.   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
  5491.     (if_then_else:SI (match_operator 4 "comparison_operator"
  5492.               [(match_operand 3 "reversible_cc_register" "")
  5493.                (const_int 0)])
  5494.              (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
  5495.              (not:SI
  5496.               (match_operand:SI 2 "s_register_operand" "r,r"))))]
  5497.   ""
  5498.   "@
  5499.    mvn%D4\\t%0, %2
  5500.    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
  5501. [(set_attr "conds" "use")
  5502.  (set_attr "length" "4,8")])
  5503.  
  5504. ;; The next two patterns occur when an AND operation is followed by a
  5505. ;; scc insn sequence 
  5506.  
  5507. (define_insn ""
  5508.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5509.     (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
  5510.              (const_int 1)
  5511.              (match_operand:SI 2 "immediate_operand" "n")))]
  5512.   ""
  5513.   "*
  5514.   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
  5515.   output_asm_insn (\"ands\\t%0, %1, %2\", operands);
  5516.   return \"mvnne\\t%0, #0\";
  5517. "
  5518. [(set_attr "conds" "clob")
  5519.  (set_attr "length" "8")])
  5520.  
  5521. (define_insn ""
  5522.   [(set (match_operand:SI 0 "s_register_operand" "=r")
  5523.     (not:SI
  5524.      (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
  5525.               (const_int 1)
  5526.               (match_operand:SI 2 "immediate_operand" "n"))))]
  5527.   ""
  5528.   "*
  5529.   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
  5530.   output_asm_insn (\"tst\\t%1, %2\", operands);
  5531.   output_asm_insn (\"mvneq\\t%0, #0\", operands);
  5532.   return \"movne\\t%0, #0\";
  5533. "
  5534. [(set_attr "conds" "clob")
  5535.  (set_attr "length" "12")])
  5536.  
  5537. ;; Push multiple registers to the stack.  The first register is in the
  5538. ;; unspec part of the insn; subsequent registers are in parallel (use ...)
  5539. ;; expressions.
  5540. (define_insn ""
  5541.   [(match_parallel 2 "multi_register_push"
  5542.     [(set (match_operand:BLK 0 "memory_operand" "=m")
  5543.       (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 2))])]
  5544.   ""
  5545.   "*
  5546. {
  5547.   char pattern[100];
  5548.   int i;
  5549.   extern int lr_save_eliminated;
  5550.  
  5551.   if (lr_save_eliminated)
  5552.     {
  5553.       if (XVECLEN (operands[2], 0) > 1)
  5554.     abort ();
  5555.       return \"\";
  5556.     }
  5557.   strcpy (pattern, \"stmfd\\t%m0!, {%|%1\");
  5558.   for (i = 1; i < XVECLEN (operands[2], 0); i++)
  5559.     {
  5560.       strcat (pattern, \", %|\");
  5561.       strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
  5562.                           0))]);
  5563.     }
  5564.   strcat (pattern, \"}\");
  5565.   output_asm_insn (pattern, operands);
  5566.   return \"\";
  5567. }"
  5568. [(set_attr "type" "store4")])
  5569.